轉自:http://yiyickf.iteye.com/blog/1047010
排序算法java版,速度排行:冒泡排序、簡單選擇排序、直接插入排序、折半插入排序、希爾排序、堆排序、歸併排序、快速排序
文章分類:Java編程
先推薦一篇關於排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html
本文思路部分來源於上篇文章,但測得的結果似乎不大相同,不知是因爲java的緣故還是因爲我算法的緣故,歡迎拍磚。
複習排序,順便比下各種算法的速度,榜單如下:
1、冒泡排序
2、簡單選擇排序
3、直接插入排序
4、折半插入排序
5、希爾排序
6、堆排序
7、歸併排序
8、快速排序
當然這是慢速排行,哈哈~~
直接上圖:單位毫秒
冒泡排序 |
簡單選擇排序 |
直接插入排序 |
折半插入排序 |
希爾排序 |
堆排序 |
歸併排序 |
快速排序 |
|
10000 個 |
1578 |
1250 |
672 |
250 |
0 |
15 |
16 |
0 |
15000 個 |
3453 |
2765 |
1563 |
531 |
16 |
15 |
16 |
0 |
20000 個 |
6140 |
4547 |
2453 |
828 |
16 |
16 |
15 |
16 |
25000 個 |
10079 |
7171 |
3969 |
1313 |
31 |
16 |
15 |
16 |
30000 個 |
14641 |
10313 |
5578 |
1906 |
31 |
31 |
16 |
31 |
35000 個 |
20141 |
14328 |
7890 |
2563 |
31 |
31 |
32 |
15 |
40000 個 |
25766 |
18359 |
10094 |
3422 |
47 |
31 |
31 |
32 |
45000 個 |
32469 |
24063 |
13062 |
4359 |
47 |
47 |
31 |
47 |
由於"希爾排序","堆排序","歸併排序","快速排序"太快,以至於在上圖幾乎是條直線,故有了下面轉爲他們準備的加強版
數量 |
希爾排序 |
堆排序 |
歸併排序 |
快速排序 |
100000 個 |
172 |
140 |
110 |
93 |
200000 個 |
469 |
406 |
235 |
234 |
300000 個 |
812 |
703 |
422 |
375 |
400000 個 |
1125 |
1031 |
516 |
531 |
500000 個 |
1406 |
1282 |
719 |
656 |
600000 個 |
1828 |
1703 |
860 |
859 |
700000 個 |
2531 |
2063 |
1000 |
968 |
800000 個 |
2735 |
2453 |
1140 |
1188 |
900000 個 |
3047 |
2843 |
1391 |
1266 |
1000000 個 |
3375 |
3187 |
1516 |
1422 |
1100000 個 |
3922 |
3500 |
1625 |
1609 |
1200000 個 |
4421 |
3954 |
1969 |
1812 |
1300000 個 |
4797 |
4422 |
2000 |
1953 |
1400000 個 |
5391 |
4797 |
2547 |
2094 |
1500000 個 |
5437 |
5219 |
2625 |
2328 |
1600000 個 |
6203 |
5546 |
2469 |
2485 |
1700000 個 |
6532 |
5953 |
2844 |
2672 |
1800000 個 |
7125 |
6421 |
2984 |
2844 |
補上代碼:
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- /**
- * 插入排序:直接插入排序、折半插入排序和系爾排序
- * 交換排序:冒泡排序和快速排序
- * 選擇排序:簡單選擇排序和堆排序
- * 歸併排序:歸併排序
- *
- * 基本思想
- * 插入排序:將第N個記錄插入到前面(N-1)個有序的記錄當中。
- * 交換排序:按照某種順序比較兩個記錄的關鍵字大小,然後根據需要交換兩個記錄的位置。
- * 選擇排序:根據某種方法選擇一個關鍵字最大的記錄或者關鍵字最小的記錄,放到適當的位置。
- *
- * 排序方法比較
- * 排序方法 平均時間 最壞時間 輔助存儲
- * 直接插入排序 O(N2) O(N2) O(1)
- * 起泡排序 O(N2) O(N2) O(1)
- * 快速排序 O(Nlog2N) O(N2) O(Nlog2N)
- * 簡單選擇排序 O(N2) O(N2) O(1)
- * 堆排序 O(Nlog2N) O(Nlog2N) O(1)
- * 歸併排序 O(Nlog2N) O(Nlog2N) O(n)
- * 基數排序 O(d(n+radix)) O(d(n+radix)) O(radix)
- *
- *
- *
- * @author Administrator
- *
- */
- public class SortTest {
- public static void main(String[] args) throws Exception {
- //測試排序是否正確
- //String[] testErr=new String[]{"冒泡排序","簡單選擇排序","直接插入排序","折半插入排序","系爾排序","堆排序","歸併排序","快速排序"};
- //new SortTest().testErr(testErr);
- //排序1(全部)
- String[] strs=new String[]{ "冒泡排序" , "簡單選擇排序" , "直接插入排序" , "折半插入排序" , "希爾排序" , "堆排序" , "歸併排序" , "快速排序" };
- new SortTest().test(strs, 10000 , 50000 , 5000 );
- //排序2(加強)
- String[] strs2=new String[]{ "希爾排序" , "堆排序" , "歸併排序" , "快速排序" };
- new SortTest().test(strs2, 100000 , 1900000 , 100000 );
- }
- private void testErr(String[] strings) throws Exception{
- //System.out.println(Arrays.toString(old));
- System.out.println(Arrays.toString(strings));
- Number[] old=getRundom(50 );
- Integer[] oo={1 , 2 , 3 , 3 , 2 , 21 , 5 , 6 , 7 , 78 , 5 , 65 , 8 , 7 , 6 , 6 , 6 , 6 , 6 , 9 , 56544 , 354 , 32 , 4 , 456 , 8 , 89 ,- 9 , 0 , 3 , 243 ,- 321 , 321 ,- 3 ,- 2 , 21 };
- old=oo;
- for (String s:strings){
- Number[] testNum=Arrays.copyOf(old, old.length);
- long begin=System.currentTimeMillis();
- SortTest.class .getMethod(s, Number[]. class ).invoke( this , (Object)testNum);
- long end=System.currentTimeMillis();
- System.out.println(s+":" +(end-begin)+ "\t" );
- System.out.println(Arrays.toString(testNum));
- }
- System.out.println();
- }
- private void test(String[] strings, long begin, long end, long step) throws Exception{
- System.out.print("數量\t" );
- for (String str:strings){
- System.out.print(str+"\t" );
- }
- System.out.println();
- for ( long i=begin;i<end;i=i+step){
- System.out.print(i+"個\t" );
- Number[] old=getRundom(i);
- for (String s:strings){
- Number[] testNum=Arrays.copyOf(old, old.length);
- long beginTime=System.currentTimeMillis();
- SortTest.class .getMethod(s, Number[]. class ).invoke( this , (Object)testNum);
- long endTime=System.currentTimeMillis();
- System.out.print((endTime-beginTime)+"\t" );
- //System.out.println(Arrays.toString(testNum));
- }
- System.out.println();
- }
- }
- private static Integer[] getRundom( long num) {
- List<Integer> list=new ArrayList<Integer>();
- for ( long i= 0 ;i<num;i++){
- int k;
- if (Math.random()> 0.5 ){
- k=(int )(Math.random()*Integer.MAX_VALUE);
- }else {
- k=(int )(Math.random()*Integer.MIN_VALUE);
- }
- list.add(k);
- }
- return list.toArray( new Integer[list.size()]);
- }
- /**
- * 插入排序————直接插入排序
- * @param data
- */
- public static void 直接插入排序(Number[] data)
- {
- Number tmp=null ;
- for ( int i= 1 ;i<data.length;i++){
- tmp = data[i];
- int j=i- 1 ;
- while (j>= 0 && tmp.doubleValue()<data[j].doubleValue()){
- data[j+1 ]=data[j];
- j--;
- }
- data[j+1 ]=tmp;
- }
- }
- /**
- * 插入排序————折半插入排序
- * @param data
- */
- public static void 折半插入排序(Number[] data)
- {
- Number tmp=null ;
- for ( int i= 1 ;i<data.length;i++){
- tmp = data[i];
- int smallpoint= 0 ;
- int bigpoint=i- 1 ;
- while (bigpoint>=smallpoint){
- int mid=(smallpoint+bigpoint)/ 2 ;
- if (tmp.doubleValue()>data[mid].doubleValue()){
- smallpoint=mid+1 ;
- }else {
- bigpoint=mid-1 ;
- }
- }
- for ( int j=i;j>smallpoint;j--){
- data[j]=data[j-1 ];
- }
- data[bigpoint+1 ]=tmp;
- }
- }
- /**
- * 插入排序————希爾排序
- * @param data
- */
- public static void 希爾排序(Number[] data)
- {
- int span=data.length/ 7 ;
- if (span== 0 )span= 1 ;
- while (span>= 1 ){
- for ( int i= 0 ;i<span;i++){
- for ( int j=i;j<data.length;j=j+span){
- //組內直接插入排序
- int p = j-span;
- Number temp = data[j];
- while ( p >= 0 && data[p].doubleValue() > temp.doubleValue()){
- data[p+span] = data[p];
- p -=span;
- }
- data[p + span] = temp;
- }
- }
- span=span/2 ;
- }
- }
- /**
- * 交換排序————冒泡排序
- *
- * @param data
- */
- public static void 冒泡排序(Number[] data)
- {
- for ( int i = 0 ; i < data.length; i++) {
- //將相鄰兩個數進行比較,較大的數往後冒泡
- for ( int j = 0 ; j < data.length - i- 1 ; j++) {
- if (data[j].doubleValue()> data[j + 1 ].doubleValue()) {
- //交換相鄰兩個數