/** * 冒泡排序:比较相邻的元素。如果第一个比第二个大,就交换他们两个。 * @param array 要排序的数组 * @return 排序号后的数组 */ public static int[] BubbleSort(int[] array){ if(array == null){ throw new RuntimeException(" srcArray is null!"); } int len = array.length; for(int i=0; i<len-1; i++){ for(int j=0; j<len-i-1; j++){ if( array[j] > array[j+1]){ swap(array, j, j+1); } } } return array; } /** * 交换数组指定位置的两个数 * @param src * @param indexL * @param indexR */ public static void swap(int[] src, int indexL, int indexR){ src[indexL] = src[indexL] ^ src[indexR]; src[indexR] = src[indexL] ^ src[indexR]; src[indexL] = src[indexL] ^ src[indexR]; }
public static void main(String[] args) throws FileNotFoundException { final String path = "C:\\sort"; //数据源 final String largeW = "largeW.txt"; //目标文件 final String largeW_bubble = "largeW_bubble.txt"; //要排序的数的个数 final int ARRAY_SIZE = 100000; int [] array = new int[ARRAY_SIZE]; //开始时间 long startTime = System.currentTimeMillis(); Scanner sc = new Scanner(new File(path,largeW)); PrintWriter pw = new PrintWriter(new File(path,largeW_bubble)); int index = 0; //读取数据 -> 数组 while(index<ARRAY_SIZE){ array[index] = sc.nextInt(); index++; } //冒一下泡 BubbleSort(array); //将排序后数组写到文件中 for(int num : array){ pw.println(num); } pw.flush(); pw.close(); sc.close(); //结束时间 long endTime = System.currentTimeMillis(); System.err.printf("冒泡排序结束,共耗时:%d毫秒, 数据量:%d ", endTime-startTime, ARRAY_SIZE); }
/** * 归并排序 * @param src 要排序的数组 * @param des 排序后的数组 */ public MergeSort(int[] src, int[] des){ //令初始化的子序列长度为1 int len = 1, n=src.length-1; while( len<n){ //当归并的趟数为奇数时,归并排序的结果存储在des数组 MergerPass(src, des, n, len); len *= 2; //当归并的趟数为偶数时,归并排序的结果存储在src数组 MergerPass(des, src, n, len); len *= 2; } } /** * 一趟归并 * @param src * @param des * @param n 待排序的数多少个 * @param len 子序列有多少个数 */ public void MergerPass(int[] src, int[] des, int n, int len ){ //从数组的第二个位置开始存放待排序列,方便计算位置 int _p = 1; //相邻的两个有序序列长度均为len,执行一次归并后指针_p前进2*len while( _p <= (n-2*len+1) ){ Merge(src, des, _p, _p+len-1, _p+2*len-1); _p += 2*len; } //相邻的两个有序序列长度分别为len和<len,执行一次归并后退出这趟归并 if( _p < (n-len+1) ){ Merge(src, des, _p, _p+len-1, n); } //只剩下一个子序列,将其copy到目标数组后退出这趟归并 else{ while(_p<=n){ des[_p] = src[_p]; _p++; } } } /** * 一次归并 * @param src 待归并数组 * @param des 目标数组 * @param start 第一个个子序列的开始位置 * @param middle 第一个子序列的结束位置 * @param end 第二个子序列的结束位置 */ public void Merge(int[] src, int[] des, int start, int middle, int end ){ // i指向第一个个子序列的首,j指向第二个子序列的首,k指向目标数组的首 int i = start, j = middle+1, k = start; //比较两个子序列的数大小,将较小的数存到目标数组对应位置 while( i<=middle && j<=end ){ if( src[i] <= src[j]){ des[k++] = src[i++]; }else{ des[k++] = src[j++]; } } //收尾工作,将剩下的数全部存到目标数组 if( i<=middle ){ while( i<=middle ){ des[k++] = src[i++]; } }else{ while( j<=end ){ des[k++] = src[j++]; } } }
public static void main(String[] args) throws FileNotFoundException { final String path = "C:\\sort"; //数据源 final String largeW = "largeW.txt"; //目标文件 final String largeW_merge = "largeW_merge.txt"; //要排序的数的个数(注意!!! 第一个数不存放数据,为了方便计算。。。) final int ARRAY_SIZE = 1000000+1; int [] array = new int[ARRAY_SIZE]; int[] des = new int[ARRAY_SIZE]; Scanner sc = new Scanner(new File(path,largeW)); PrintWriter pw = new PrintWriter(new File(path,largeW_merge)); //注意!!! 归并排序的数组的第一个位置没有存放数 int index = 1; //读取数据 -> 数组 while(index<ARRAY_SIZE){ array[index] = sc.nextInt(); index++; } //开始时间 long startTime = System.currentTimeMillis(); //归并排序 new MergeSort(array,des); //结束时间 long endTime = System.currentTimeMillis(); System.err.printf("归并排序结束,共耗时:%d毫秒, 数据量:%d ", endTime-startTime, ARRAY_SIZE-1); //将排序后数组写到文件中 for(int i=1; i<ARRAY_SIZE; i++){ pw.println(array[i]); } pw.flush(); pw.close(); sc.close(); }
每走一趟扫描 n 个数, 共走 log2n趟。
时间复杂度是: O(n) = n * log2n