对于较少的数进行排序,冒泡和归并算法的优势区分并不明显,然而,这次对长度为1000000的数组进行排序。使用冒泡排序算法,简直无情,历时43分钟有余(2619秒)!而归并排序算法对其实现仅仅使用了264毫秒,你没看错!相差的除了数值还有一个数量级!由此可见,算法的优化对于机器处理来说,其重要性不言而喻。
冒泡排序参考资料:http://zh.wikipedia.org/wiki/%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F
归并排序参考资料:http://zh.wikipedia.org/wiki/%E5%90%88%E4%BD%B5%E6%8E%92%E5%BA%8F
程序实现:
import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.text.DateFormat; import java.util.Scanner; public class Txt2Sort { //返回冒泡排序所用时间 public long bubbleSort(int[] dataArray){ DateFormat dfDefault = DateFormat.getInstance(); long startTime = System.currentTimeMillis(); System.out.println("\n冒泡排序开始时间:"+dfDefault.format(startTime)); //冒泡排序算法 for(int i=1,lineCount=dataArray.length;i<lineCount;i++) for(int j=0;j<lineCount-i;j++){ if(dataArray[j]>dataArray[j+1]){ int t = dataArray[j]; dataArray[j] = dataArray[j+1]; dataArray[j+1] = t; } } long endTime = System.currentTimeMillis(); System.out.println("冒泡排序结束时间:"+dfDefault.format(endTime)); long useTimeSeconds = (long)((endTime - startTime)/1000); return useTimeSeconds; } //写入文件使用时长 public long writeToFile(int[] array,String fileName) throws FileNotFoundException{ DateFormat dfDefault = DateFormat.getInstance();//获取时间,格式:3/27/14 10:50 PM PrintWriter pw = new PrintWriter(new File(fileName)); long startTime = System.currentTimeMillis(); System.out.println("\n写入文件开始时间:"+dfDefault.format(startTime)); for(int i=0,lineCount=array.length;i<lineCount;i++){ pw.println(array[i]); } pw.close(); long endTime = System.currentTimeMillis(); System.out.println("写入文件结束时间:"+dfDefault.format(endTime)); long useTimeMills = (long)(endTime - startTime); //单位:毫秒 return useTimeMills; } //返回归并排序使用的时间 public long mergeSort(int[] needSortArray,int arrayLength,String fileName) throws FileNotFoundException{ int[] medium = new int[arrayLength]; DateFormat dfDefault = DateFormat.getInstance(); long startTime = System.currentTimeMillis(); System.out.println("归并排序开始时间:"+dfDefault.format(startTime)); //排序 MergeAll(needSortArray, medium, arrayLength); long endTime = System.currentTimeMillis(); System.out.println("归并排序结束时间:"+dfDefault.format(endTime)); this.writeToFile(needSortArray, fileName); long useTimeSeconds = (long)(endTime - startTime); return useTimeSeconds; } //一次相邻数组排序 public void MergeFirst(int[] r,int[] r1, int s,int m,int t){ //相邻有序序列r[s]~r[m]和r[m+1]~r[t],合成有序序列r1[s]~r1[t] //i,j分别指向相邻有序序列的当前元素,k指向合成有序序列的当前元素 int i=s,j=m,k=s; while(i<m && j<t){ if(r[i]<=r[j]) r1[k++] = r[i++]; else r1[k++] = r[j++]; } //处理未排序的序列,前半部分和后半部分 if(i<m) while(i<m) r1[k++]=r[i++]; else while(j<t) r1[k++]=r[j++]; } //一层相邻数组排序,从下标为0开始存放待排序列 public void MergeSecond(int[] r,int[] r1,int n,int h){ int i=0; while(i<=n-2*h){ MergeFirst(r, r1, i,i+h,i+2*h); i+=2*h; } //最后一个序列长度小于h(子序列的数组长度) if(i<n-h) MergeFirst(r, r1, i,i+h,n); //排至剩下最后一个子序列 else for(int k=i;k<n;k++) r1[k]=r[k]; } //全体二路归并排序非递归实现 public void MergeAll(int[] r,int[] r1,int n){ int h=1;//h为初始子序列(h)长度 while(h<n){ MergeSecond(r, r1, n, h);//待排序列r传至r1 h=2*h; MergeSecond(r1, r, n, h);//待排序列r1传回r h=2*h; } } //全体二路归并排序递归实现 public static void main(String[] args) throws FileNotFoundException{ //从文件读取数据 int[] readCount = new int[1000000]; Scanner scan = new Scanner(new File(args[0]));//第一个个参数指定读取的文件名 while(scan.hasNextInt()){ for(int n=0,lineCount= readCount.length;n<lineCount;n++){ readCount[n] = scan.nextInt(); } } scan.close(); //冒泡排序调用,返回排序时长 Txt2Sort t = new Txt2Sort(); long useSortTime = t.bubbleSort(readCount); System.out.println("\n冒泡排序法使用时长:"+useSortTime+" seconds"); //写入文件调用,返回写入时长,第二个参数指定生成的文件名 long useWriteTime = t.writeToFile(readCount,args[1]); System.out.println("写入文件使用时长:"+useWriteTime+" mills"); long bubbleUseAllTime = useSortTime+useWriteTime; System.out.println("冒泡排序总共使用时长:"+bubbleUseAllTime+" seconds"); //归并排序调用,返回排序时长 long MegerUseAllTime = t.mergeSort(readCount, readCount.length,args[1]); System.out.println("归并排序使用时长:"+MegerUseAllTime+" mills"); } }
测试结果: