排序算法

测试排序的效率,为什么:希尔排序>归并排序>快速排序?20

我看看几篇排序的算法的文章,大家都说效率一般都是:快速排序>归并排序>希尔排序

然后就用java自己动手测了一下,测试结果却是:希尔排序>归并排序>快速排序

而且当数据量过大时,归并排序 和 快速排序 会出现栈溢出.

 

以下是我写的源代码,请帮我分析一下是什么原因?

 

Java代码   收藏代码
  1. package com.test;  
  2.   
  3. import java.util.Arrays;  
  4. import java.util.Random;  
  5.   
  6. public class Sort {  
  7.     public static void main(String[] args) {  
  8.         int[] arr = new int[400000];  
  9.         Random r = new Random();  
  10.   
  11.         long start, end;  
  12.   
  13.         init(arr, r);  
  14.         System.out.print("希尔排序...");  
  15.         start = System.currentTimeMillis();  
  16.         sort1(arr);  
  17.         end = System.currentTimeMillis();  
  18.         System.out.println("完成" + (end - start));  
  19.         //System.out.println(Arrays.toString(arr));  
  20.   
  21.         init(arr, r);  
  22.         System.out.print("归并排序...");  
  23.         start = System.currentTimeMillis();  
  24.         arr = sort2(arr, 0, arr.length - 1);  
  25.         end = System.currentTimeMillis();  
  26.         System.out.println("完成" + (end - start));  
  27.         //System.out.println(Arrays.toString(arr));  
  28.   
  29.         init(arr, r);  
  30.         System.out.print("快速排序...");  
  31.         start = System.currentTimeMillis();  
  32.         sort3(arr, 0, arr.length - 1);  
  33.         end = System.currentTimeMillis();  
  34.         System.out.println("完成" + (end - start));  
  35.         //System.out.println(Arrays.toString(arr));  
  36.   
  37.     }  
  38.   
  39.     /** 
  40.      * 初始化 
  41.      */  
  42.     private static void init(int[] arr, Random r) {  
  43.         System.out.print("\n初始化...");  
  44.         for (int i = 0; i < arr.length; i++) {  
  45.             arr[i] = r.nextInt(100);  
  46.         }  
  47.         //System.out.println("\n" + Arrays.toString(arr));  
  48.     }  
  49.   
  50.     /** 
  51.      * 希尔排序 
  52.      */  
  53.     private static void sort1(int[] a) {  
  54.         int i, j, temp, increment;  
  55.         // increment增量缩短,当增量为1时,即把整个数组进行插入排序  
  56.         for (increment = a.length / 3; increment > 0; increment /= 3) {  
  57.             for (i = increment; i < a.length; i++) {  
  58.                 temp = a[i];  
  59.                 for (j = i - increment; j >= 0 && temp < a[j]; j -= increment) {  
  60.                     a[j + increment] = a[j];  
  61.                 }  
  62.                 a[j + increment] = temp;  
  63.             }  
  64.   
  65.         }  
  66.     }  
  67.   
  68.     /** 
  69.      * 归并排序 
  70.      * left,right参数表示:把a数组中left--right之间的元素排序 
  71.      * 排序结果以新数组返回. 
  72.      */  
  73.     private static int[] sort2(int[] a, int left, int right) {  
  74.             //判断递归结束条件  
  75.             if (right <= left) return new int[] { a[left] };  
  76.               
  77.             //从数组中间切成左右两部分,mid为右边部分的起始下标  
  78.             int mid = (left + right + 1) / 2;  
  79.             //第一步:用递归把数组左边排序  
  80.             int[] a1 = sort2(a, left, mid - 1);  
  81.             //第二步:用递归把数组右边排序  
  82.             int[] a2 = sort2(a, mid, right);  
  83.               
  84.             //第三步:归并操作,把左右两边序列合并到新的数组  
  85.             int[] result = new int[right - left + 1];  
  86.             int i = 0, j = 0, k = 0;  
  87.             while (i < a1.length && j < a2.length) {  
  88.                 if (a1[i] < a2[j])  
  89.                     result[k++] = a1[i++];  
  90.                 else  
  91.                     result[k++] = a2[j++];  
  92.             }  
  93.             while (j < a2.length) {  
  94.                 result[k++] = a2[j++];  
  95.             }  
  96.             while (i < a1.length) {  
  97.                 result[k++] = a1[i++];  
  98.             }  
  99.             return result;  
  100.     }  
  101.   
  102.     /** 
  103.      * 快速排序 
  104.      * left,right参数表示:把a数组中left--right之间的元素排序 
  105.      */  
  106.     private static void sort3(int[] a, int left, int right) {  
  107.         // 第四步:判断结束递归的条件  
  108.         if(left>=right) return;  
  109.           
  110.         // 第一步:以left为基数,把a分成左右两部分,使左边部分小于右边部分  
  111.         int i = left;//最终i==j;  
  112.         for (int b=1,j=right; i < j;) {// 最初b=1,表示以left为基数  
  113.             if (a[i] > a[j]) {//交换位置  
  114.                 int temp = a[i];  
  115.                 a[i] = a[j];  
  116.                 a[j] = temp;  
  117.                 if (b==1) i++; else j--;//应基数位置不同,处理也不同  
  118.                 b = -b;//交换位置后,基数位置变化,b=1,表示以left为基数  
  119.             } else {  
  120.                 if (b==1) j--; else i++;//应基数位置不同,处理也不同  
  121.             }  
  122.         }  
  123.         // 第二步:递归排序左部分(left到i-1)  
  124.         sort3(a,left,i-1);  
  125.         // 第三步:递归排序右部分(i+1到right)  
  126.         sort3(a,i+1,right);  
  127.     }  
  128. }  

 运行结果如下:

 

初始化...希尔排序...完成40

初始化...归并排序...完成53

初始化...快速排序...完成1411
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值