第三周作业——冒泡排序和归并排序

来源:互联网 发布:濒死状态知乎 编辑:程序博客网 时间:2024/05/22 06:27

冒泡排序


用Java实现冒泡排序,代码如下:
/** * 冒泡排序:比较相邻的元素。如果第一个比第二个大,就交换他们两个。 * @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];}

测试数据:largeW.txt。由于信息量略大,故先选取前10,000和前100,000条数据进行测试,代码如下:
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);               }

运行结果:

数据量为10,000时,运行时间是1.666秒


数据量为100,000时,运行时间是75.063秒


数据量为1000,000时,运行时间是:2.33小时...



归并排序


用Java实现归并排序,代码如下:
/** * 归并排序 * @param src 要排序的数组 * @param des 排序后的数组 */public  MergeSort(int[] src, int[] des){//令初始化的子序列长度为1int 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*lenwhile( _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++];}}}

测试数据:largeW.txt。虽然信息量略大,但就算是1000,000条数据也秒排序!代码如下:
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();        }



运行结果:

数据量为10,000时,运行时间是:0.056秒!


数据量为100,000时,运行时间是:0.082秒!!


数据量为1000,000时,运行时间是:0.583秒!!!




总结冒泡排序和归并排序


冒泡排序:

走第一趟时扫描 n-1 个数,第二趟时扫描 n-2 个数...
时间复杂度是: O(n) = (n-1+1)*(n-1)/2  --> O(n) = n^2

归并排序:

每走一趟扫描 n 个数, 共走 log2n趟。

时间复杂度是: O(n) = n * log2n


0 0
原创粉丝点击