常见排序算法实现和性能对比

一、相关基本知识
1、稳定排序和非稳定排序
    在待排序的文件中,若存在多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的相对次序保持不变,该排序方法是稳定的;
    若具有相同关键字的记录之间的相对次序发生改变,则称这种排序方法是不稳定的。
2、内排序和外排序
    在排序过程中,所有需要排序的数都在内存,并在内存中调整它们的存储顺序,称为内排序;
    在排序过程中,只有部分数被调入内存,并借助内存调整数在外存中的存放顺序排序方法称为外排序。
3、算法的时间复杂度和空间复杂度
    所谓算法的时间复杂度,是指执行算法所需要的计算工作量。 
    所谓算法的空间复杂度,一般是指执行这个算法所需要的内存空间。

二、常见算法列举

1、稳定
冒泡排序(bubble sort) — O(n2)
鸡尾酒排序 (Cocktail sort, 双向的冒泡排序) — O(n2)
插入排序 (insertion sort)— O(n2)
桶排序 (bucket sort)— O(n); 需要 O(k) 额外空间
计数排序 (counting sort) — O(n+k); 需要 O(n+k) 额外空间
合并排序 (merge sort)— O(n log n); 需要 O(n) 额外空间
原地合并排序 — O(n2)
二叉排序树排序 (Binary tree sort) — O(n log n)期望时间; O(n2)最坏时间; 需要 O(n) 额外空间
鸽巢排序 (Pigeonhole sort) — O(n+k); 需要 O(k) 额外空间
基数排序 (radix sort)— O(n·k); 需要 O(n) 额外空间
Gnome 排序 — O(n2)
图书馆排序 — O(n log n) with high probability, 需要 (1+ε)n 额外空间

2、不稳定
选择排序 (selection sort)— O(n2)
希尔排序 (shell sort)— O(n log n) 如果使用最佳的现在版本
组合排序 — O(n log n)
堆排序 (heapsort)— O(n log n)sq
平滑排序 — O(n log n)
快速排序 (quicksort)— O(n log n) 期望时间, O(n2) 最坏情况; 对于大的、乱数列表一般相信是最快的已知排序
Introsort — O(n log n)
Patience sorting — O(n log n + k) 最坏情况时间,需要 额外的 O(n + k) 空间,也需要找到最长的递增子串行(longest increasing subsequence)

3、不实用的排序算法
Bogo排序 — O(n × n!) 期望时间,无穷的最坏情况。
Stupid sort — O(n3); 递归版本需要 O(n2) 额外存储器
珠排序(Bead sort) — O(n) or O(√n), 但需要特别的硬件
Pancake sorting — O(n), 但需要特别的硬件

三、实现代码

  1 /*
  2 *
  3 * Copyright (c) 2012,
  4 * All rights reserved.
  5 *
  6 * 文件名称:sort.cpp
  7 * 文件标识:
  8 * 摘 要:各种常见排序算法实现
  9 *
 10 **************************************************
 11 *
 12 * 当前版本:V0.01
 13 * 作 者: (tojoyccnu@163.com)
 14 * 创建日期:2012.7.11
 15 *
 16 * 修订版本:V0.001
 17 * 作 者:xionghuatao
 18 * 创建日期:2012.7.11
 19 * 修订描述:创建文件
 20 *
 21 */
 22 
 23 #include <stdio.h>
 24 #include <stdlib.h>
 25 #include <memory.h>
 26 #include <windows.h>
 27 
 28 void printarray(int *data, int size);
 29 
 30 __int64 FileTimeToQuadWord(PFILETIME pft) {
 31   return (Int64ShllMod32(pft->dwHighDateTime, 32) | pft->dwLowDateTime);
 32 
 33 }
 34 
 35 /*
 36  函数名称:select_sort
 37  算法简述: 选择排序
 38  1、在待排序序列中选择最小的记录与第一个位置交换。
 39  2、在剩余待排序序列再次选择最小记录与第二个位置交换。
 40  3、重复2
 41 
 42  时间复杂度: O(n2)
 43  空间复杂度: O(1)
 44  稳定性:不稳定
 45  */
 46 void select_sort(int *data, int datasize) {
 47   int index;
 48   int tmpindex;
 49   int minindex;
 50 
 51   for (index = 0; index < datasize; ++index) {
 52     minindex = index;
 53 
 54     //待排序序列中,查找最小关键字数据
 55     for (tmpindex = index + 1; tmpindex < datasize; ++tmpindex) {
 56       if (data[minindex] > data[tmpindex]) {
 57         minindex = tmpindex;
 58       }
 59     }
 60 
 61     if (minindex != index) {
 62       int tmp = data[index];
 63       data[index] = data[minindex];
 64       data[minindex] = tmp;
 65     }
 66   }
 67 }
 68 
 69 /*
 70  函数名称:gnome_sort 地精算法
 71  算法简述: 号称最简单的排序算法,只有一层循环,默认情况下前进冒泡,一旦遇到冒泡的情况发生就往回冒,直到把这个数字放好为止。
 72  时间复杂度: O(n2)
 73  空间复杂度: O(1)
 74  稳定性:稳定
 75  */
 76 void gnome_sort(int *data, int datasize) {
 77   int i = 0;
 78   int tmp;
 79 
 80   while (i < datasize) {
 81     if (i == 0 || data[i - 1] < data[i]) {
 82       ++i;
 83     } else {
 84       tmp = data[i];
 85       data[i] = data[i - 1];
 86       data[--i] = tmp;
 87     }
 88   }
 89 }
 90 
 91 /*
 92  函数名称:bubble_sort 冒泡排序
 93  算法简述: 依次比较相邻的两个数,将小数放在前面,大数放在后面
 94  时间复杂度: O(n2)
 95  空间复杂度: O(1)
 96  稳定性:稳定
 97  */
 98 void bubble_sort(int *data, int datasize) {
 99   int i, j;
100   int flag;
101 
102   for (i = datasize - 1; i >= 0; --i) {
103     flag = 0;
104     for (j = 0; j < i; ++j) {
105       if (data[j] > data[j + 1]) {
106         int tmp = data[j];
107         data[j] = data[j + 1];
108         data[j + 1] = tmp;
109         flag = 1;
110       }
111     }
112 
113     //flag == 0 表示已排序,为发生交换
114     if (!flag)
115       return;
116   }
117 }
118 
119 /*
120  函数名称:cocktail_sort
121  算法简述: 鸡尾酒排序(冒泡排序的轻微改变,来回排序)
122  时间复杂度: O(n2)
123  空间复杂度: O(1)
124  稳定性:稳定
125  */
126 void cocktail_sort(int *data, int datasize) {
127   int bottom = 0;
128   int top = datasize - 1;
129   int swap = 1;
130   int i, tmpdata;
131 
132   while (swap) {
133     swap = 0;
134 
135     //至上而下,冒泡排序最大值
136     for (i = 0; i < top; ++i) {
137       if (data[i] > data[i + 1]) {
138         tmpdata = data[i];
139         data[i] = data[i + 1];
140         data[i + 1] = tmpdata;
141         swap = 1;
142       }
143     }
144 
145     --top;
146 
147     //至下而上, 冒泡排序最小值
148     for (i = top - 1; i >= bottom; --i) {
149       if (data[i] > data[i + 1]) {
150         tmpdata = data[i];
151         data[i] = data[i + 1];
152         data[i + 1] = tmpdata;
153         swap = 1;
154       }
155     }
156 
157     ++bottom;
158   }
159 }
160 
161 /*
162  函数名称:insert_sort 简单插入排序
163  算法简述: 插入排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。
164  希尔排序是基于插入排序的以下两点性质而提出改进方法的:插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
165  但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位
166 
167  时间复杂度: O(n2)
168  空间复杂度: O(1)
169  稳定性:稳定
170  */
171 void insert_sort(int *data, int size) {
172   int i, j, t;
173 
174   for (i = 1; i < size; ++i) {
175     t = data[i];
176 
177     for (j = i - 1; j >= 0 && data[j] > t; --j) {
178       data[j + 1] = data[j];
179     }
180 
181     data[j + 1] = t;
182   }
183 }
184 
185 /*
186  函数名称:shell_sort 希尔排序
187  算法简述: 希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。
188  希尔排序是基于插入排序的以下两点性质而提出改进方法的:插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
189  但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位
190 
191  时间复杂度: O(n log n)
192  空间复杂度: O(1)
193  稳定性:不稳定
194  */
195 
196 void shell_sort(int *data, int size) {
197   int i, j;
198   int d;
199   int tmp;
200 
201   for (d = size / 2; d > 0; d /= 2) {
202     for (i = d; i < size; ++i) {
203       tmp = data[i];
204       for (j = i - d; j >= 0 && tmp < data[j]; j -= d) {
205         data[j + d] = data[j];
206       }
207       data[j + d] = tmp;
208     }
209   }
210 }
211 
212 /*
213  函数名称:merge_sort 归并排序,二路归并排序, 自底向上
214  算法简述: 归并排序是建立在归并操作上的一种有效的排序算法。
215  将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,
216  再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并
217 
218  时间复杂度: O(n log n)
219  空间复杂度: O(n)
220  稳定性:稳定
221  */
222 int merge(int *data, int low, int midd, int high) {
223   if (!(NULL != data && low >= 0 && low <= midd && low <= high)) {
224     return 1;
225   }
226 
227   int *tmp = (int *) malloc((high - low + 1) * sizeof(int));
228 
229   if (NULL == tmp) {
230     return 2;
231   }
232 
233   int i = low;
234   int j = midd + 1;
235   int index = 0;
236 
237   while (i <= midd && j <= high) {
238     if (data[i] <= data[j]) {
239       tmp[index++] = data[i++];
240     } else {
241       tmp[index++] = data[j++];
242     }
243   }
244 
245   while (i <= midd) {
246     tmp[index++] = data[i++];
247   }
248 
249   while (j <= high) {
250     tmp[index++] = data[j++];
251   }
252 
253   memcpy((void *) (data + low), tmp, sizeof(int) * (high - low + 1));
254   free(tmp);
255 
256   return 0;
257 }
258 
259 void merge_pass(int *data, int n, int size) {
260   int i;
261   int sortlength = 2 * n;
262 
263   for (i = 0; (i + sortlength - 1) < size; i = i + sortlength) {
264     merge(data, i, i + n - 1, i + sortlength - 1);
265   }
266 
267   if (i + n - 1 < size - 1) {
268     merge(data, i, i + n - 1, size - 1);
269   }
270 }
271 
272 void merge_sort(int *data, int size) {
273   int i;
274 
275   for (i = 1; i < size; i = (i << 1)) {
276     merge_pass(data, i, size);
277   }
278 }
279 
280 //堆排序用到的辅助函数
281 int parent(int i) {
282   return (int) ((i - 1) / 2);
283 }
284 
285 int left(int i) {
286   return (2 * i + 1);
287 }
288 
289 int right(int i) {
290   return (2 * i + 2);
291 }
292 
293 /*
294  函数名称:heap_sort 堆排序
295  算法简述: 利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,
296  使得每次从无序中选择最大记录(最小记录)变得简单
297 
298  时间复杂度: O(n log n)
299  空间复杂度: O(1)
300  稳定性:不稳定
301  */
302 void maxheap_shit(int *data, int index, int size) {
303   int i, j;
304   int tmp;
305 
306   i = index;
307   j = 2 * i + 1;  //左子节点
308 
309   while (j < size) {
310     if (j + 1 < size && data[j + 1] > data[j]) {
311       ++j;
312     }
313 
314     if (data[j] > data[i]) {
315       tmp = data[i];
316       data[i] = data[j];
317       data[j] = tmp;
318 
319       i = j;
320       j = 2 * i + 1;
321     } else {
322       break;
323     }
324   }
325 }
326 
327 void heap_sort(int *data, int size) {
328   int i, k, tmp;
329 
330   for (i = (size - 1) / 2; i >= 0; --i) {
331     maxheap_shit(data, i, size);
332   }
333 
334   for (k = size - 1; k > 0; --k) {
335     tmp = data[k];
336     data[k] = data[0];
337     data[0] = tmp;
338 
339     maxheap_shit(data, 0, k);
340   }
341 }
342 
343 /*
344  函数名称:quick_sort 快速排序
345  算法简述: 希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。
346  希尔排序是基于插入排序的以下两点性质而提出改进方法的:插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
347  但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位
348 
349  时间复杂度: O(n log n)
350  空间复杂度: O(1)
351  稳定性:不稳定
352  */
353 
354 int midian3(int *data, int first, int midian, int end) {
355   if (data[first] < data[midian]) {
356     if (data[midian] < data[end]) {
357       return midian;
358     } else if (data[first] < data[end]) {
359       return end;
360     } else {
361       return first;
362     }
363   } else if (data[first] < data[end]) {
364     return first;
365   } else if (data[midian] < data[end]) {
366     return end;
367   } else {
368     return midian;
369   }
370 
371   return first;
372 }
373 
374 void swap_num(int *a, int *b) {
375   int tmp = *a;
376 
377   *a = *b;
378   *b = tmp;
379 }
380 
381 int partition(int *data, int left, int right, int p) {
382   swap_num(&data[p], &data[left]);
383   int pivot = data[left];
384 
385   while (left < right) {
386     while (left < right && data[right] > pivot) {
387       --right;
388     }
389 
390     if (left != right) {
391       data[left] = data[right];
392       left++;
393     }
394 
395     while (left < right && data[left] < pivot) {
396       ++left;
397     }
398 
399     if (left != right) {
400       data[right] = data[left];
401       right--;
402     }
403   }
404 
405   data[left] = pivot;
406 
407   return left;
408 }
409 
410 void q_sort(int *data, int tmpleft, int tmpright) {
411   if (tmpleft >= tmpright)
412     return;
413 
414   int pivot = partition(
415       data, tmpleft, tmpright,
416       midian3(data, tmpleft, tmpright, tmpleft + (tmpright - tmpleft) / 2));
417 
418   q_sort(data, tmpleft, pivot - 1);
419 
420   q_sort(data, pivot + 1, tmpright);
421 }
422 
423 void quick_sort(int *data, int size) {
424   q_sort(data, 0, size - 1);
425 }
426 
427 //log 函数
428 int lg(int n) {
429   int k;
430   for (k = 0; n > 1; n >>= 1)
431     ++k;
432   return k;
433 }
434 
435 int partition2(int *data, int tmpleft, int tmpright, int p) {
436   int i;
437   int index = tmpleft;
438 
439   swap_num(&data[p], &data[tmpright]);
440   int pivot = data[tmpright];
441 
442   for (i = tmpleft; i < tmpright; i++) {
443     if (data[i] < pivot)
444       swap_num(&data[index++], &data[i]);
445   }
446 
447   //将标准与index指向的元素交换,返回index,即分割位置
448   swap_num(&data[tmpright], &data[index]);
449   return index;
450 }
451 
452 void intro_q_sort(int *data, int begin, int end, int depthlimt) {
453   if (begin >= end)
454     return;
455 
456   if (end - begin + 1 >= 16) {
457     if (depthlimt == 0) {
458       //heap_rangesort(data, begin, end);
459       heap_sort(&data[begin], end - begin + 1);
460       return;
461     }
462 
463     --depthlimt;
464 
465     int pivot = partition(data, begin, end,
466                           midian3(data, begin, begin + (end - begin) / 2, end));
467     intro_q_sort(data, pivot + 1, end, depthlimt);
468     intro_q_sort(data, begin, pivot - 1, depthlimt);
469 
470   } else {
471     insert_sort(&data[begin], end - begin + 1);
472   }
473 }
474 
475 void introsort(int *data, int size) {
476   if (size != 1) {
477     intro_q_sort(data, 0, size - 1, lg(size));
478 
479     insert_sort(data, size);
480   }
481 }
482 
483 void printarray(int *data, int size) {
484   int i = 0;
485 
486   for (i = 0; i < size; i++) {
487     printf("%d ", data[i]);
488 
489     if (i && (i % 15 == 0)) {
490       printf("\n");
491     }
492   }
493 
494   printf("\n");
495 }
496 
497 #define NUMCNT  50000
498 
499 typedef void (*pfsortfunc)(int *data, int size);
500 
501 typedef struct sort_item {
502   char sortinfo[60];
503   pfsortfunc on_sort;
504 } ST_sort_item;
505 
506 static struct sort_item sort_list[] = { { "IntroSort 内省排序算法", introsort }, {
507     "ShellSort 希尔排序算法", shell_sort }, { "QuickSort 快速排序算法", quick_sort }, {
508     "HeapSort  堆排序算法  ", heap_sort }, { "MergeSort 归并排序算法", merge_sort } };
509 
510 void main() {
511   int *beforesort;
512   int *tmpsort;
513   int i;
514   int sizelen = NUMCNT;
515   int bytelen = sizelen * sizeof(int);
516   int tmp = 0;
517 
518   srand (GetTickCount());
519 
520   for(  tmp = 0; tmp < 20; tmp++)
521   {
522     sizelen = NUMCNT * (tmp + 1);
523     bytelen = sizelen * sizeof(int);
524     beforesort = (int *)malloc(bytelen);
525     tmpsort = (int *)malloc(bytelen);
526 
527     if (NULL == beforesort || NULL == tmpsort)
528     {
529       continue;
530     }
531 
532     //获得原始数据
533     for (i = 0; i < sizelen; i++)
534     {
535       beforesort[i] = rand() %1000000 + rand() % 9000;
536     }
537 
538     printf("第 %d 次, 数据规模 %d\n", tmp + 1, sizelen);
539 
540     int k;
541     for (k = 0; k < sizeof(sort_list) / sizeof(struct sort_item); k++)
542     {
543 
544       struct sort_item *ptmpitem = &sort_list[k];
545 
546       memcpy(tmpsort, beforesort, bytelen);
547 
548       FILETIME ftKernelTimeStart, ftKernelTimeEnd;
549       FILETIME ftUserTimeStart, ftUserTimeEnd;
550       FILETIME ftDummy;
551       __int64 qwKernelTimeElapsed, qwUserTimeElapsed, qwTotalTimeElapsed;
552 
553       int start1 = GetTickCount();
554 
555       GetThreadTimes(GetCurrentThread(), &ftDummy, &ftDummy,
556       &ftKernelTimeStart, &ftUserTimeStart);    //取得开始时间
557 
558       ptmpitem->on_sort(tmpsort, sizelen);
559 
560       GetThreadTimes(GetCurrentThread(), &ftDummy, &ftDummy,
561       &ftKernelTimeEnd, &ftUserTimeEnd);//取得结束时间
562       int end1 = GetTickCount();
563 
564       qwKernelTimeElapsed = FileTimeToQuadWord(&ftKernelTimeEnd) - FileTimeToQuadWord(&ftKernelTimeStart);
565       qwUserTimeElapsed = FileTimeToQuadWord(&ftUserTimeEnd) - FileTimeToQuadWord(&ftUserTimeStart);
566 
567       qwTotalTimeElapsed = qwKernelTimeElapsed + qwUserTimeElapsed;
568 
569       printf("%s: 耗时: %8d ms, %8ld 100ns\n", ptmpitem->sortinfo, end1 - start1, qwTotalTimeElapsed);
570 
571     }
572 
573     printf("\n");
574 
575     free(beforesort);
576     free(tmpsort);
577   }
578 
579   getchar();
580 }

四、各算法性能

第 1 次, 数据规模 50000
IntroSort 内省排序算法: 耗时:       16 ms,   156001 100ns
ShellSort 希尔排序算法: 耗时:       15 ms,   156001 100ns
QuickSort 快速排序算法: 耗时:       16 ms,   156001 100ns
HeapSort  堆排序算法  : 耗时:       16 ms,   156001 100ns
MergeSort 归并排序算法: 耗时:      172 ms,  1560010 100ns

第 2 次, 数据规模 100000
IntroSort 内省排序算法: 耗时:       31 ms,   312002 100ns
ShellSort 希尔排序算法: 耗时:       47 ms,   468003 100ns
QuickSort 快速排序算法: 耗时:       47 ms,   312002 100ns
HeapSort  堆排序算法  : 耗时:       47 ms,   468003 100ns
MergeSort 归并排序算法: 耗时:      577 ms,  5148033 100ns

第 3 次, 数据规模 150000
IntroSort 内省排序算法: 耗时:       31 ms,   312002 100ns
ShellSort 希尔排序算法: 耗时:       78 ms,   780005 100ns
QuickSort 快速排序算法: 耗时:       63 ms,   468003 100ns
HeapSort  堆排序算法  : 耗时:       93 ms,   624004 100ns
MergeSort 归并排序算法: 耗时:      484 ms,  4680030 100ns

第 4 次, 数据规模 200000
IntroSort 内省排序算法: 耗时:       46 ms,   468003 100ns
ShellSort 希尔排序算法: 耗时:      109 ms,  1092007 100ns
QuickSort 快速排序算法: 耗时:       63 ms,   624004 100ns
HeapSort  堆排序算法  : 耗时:       93 ms,   936006 100ns
MergeSort 归并排序算法: 耗时:      609 ms,  6084039 100ns

第 5 次, 数据规模 250000
IntroSort 内省排序算法: 耗时:       62 ms,   624004 100ns
ShellSort 希尔排序算法: 耗时:      141 ms,  1404009 100ns
QuickSort 快速排序算法: 耗时:       78 ms,   780005 100ns
HeapSort  堆排序算法  : 耗时:      124 ms,  1248008 100ns
MergeSort 归并排序算法: 耗时:      765 ms,  7488048 100ns

第 6 次, 数据规模 300000
IntroSort 内省排序算法: 耗时:       78 ms,   780005 100ns
ShellSort 希尔排序算法: 耗时:      172 ms,  1716011 100ns
QuickSort 快速排序算法: 耗时:       93 ms,   780005 100ns
HeapSort  堆排序算法  : 耗时:      141 ms,  1404009 100ns
MergeSort 归并排序算法: 耗时:     1623 ms, 15756101 100ns

第 7 次, 数据规模 350000
IntroSort 内省排序算法: 耗时:       93 ms,   936006 100ns
ShellSort 希尔排序算法: 耗时:      203 ms,  2028013 100ns
QuickSort 快速排序算法: 耗时:      109 ms,  1092007 100ns
HeapSort  堆排序算法  : 耗时:      188 ms,  1872012 100ns
MergeSort 归并排序算法: 耗时:     1965 ms, 19032122 100ns

第 8 次, 数据规模 400000
IntroSort 内省排序算法: 耗时:       94 ms,   936006 100ns
ShellSort 希尔排序算法: 耗时:      249 ms,  2340015 100ns
QuickSort 快速排序算法: 耗时:      125 ms,  1092007 100ns
HeapSort  堆排序算法  : 耗时:      234 ms,  2184014 100ns
MergeSort 归并排序算法: 耗时:     2200 ms, 21372137 100ns

第 9 次, 数据规模 450000
IntroSort 内省排序算法: 耗时:      156 ms,  1404009 100ns
ShellSort 希尔排序算法: 耗时:      266 ms,  2496016 100ns
QuickSort 快速排序算法: 耗时:      140 ms,  1404009 100ns
HeapSort  堆排序算法  : 耗时:      265 ms,  2652017 100ns
MergeSort 归并排序算法: 耗时:     2559 ms, 24960160 100ns

第 10 次, 数据规模 500000
IntroSort 内省排序算法: 耗时:      141 ms,  1404009 100ns
ShellSort 希尔排序算法: 耗时:      312 ms,  2808018 100ns
QuickSort 快速排序算法: 耗时:      156 ms,  1404009 100ns
HeapSort  堆排序算法  : 耗时:      281 ms,  2808018 100ns
MergeSort 归并排序算法: 耗时:     2714 ms, 26520170 100ns

第 11 次, 数据规模 550000
IntroSort 内省排序算法: 耗时:      141 ms,  1404009 100ns
ShellSort 希尔排序算法: 耗时:      343 ms,  3432022 100ns
QuickSort 快速排序算法: 耗时:      172 ms,  1716011 100ns
HeapSort  堆排序算法  : 耗时:      296 ms,  2964019 100ns
MergeSort 归并排序算法: 耗时:     3011 ms, 29484189 100ns

第 12 次, 数据规模 600000
IntroSort 内省排序算法: 耗时:      141 ms,  1404009 100ns
ShellSort 希尔排序算法: 耗时:      390 ms,  3900025 100ns
QuickSort 快速排序算法: 耗时:      187 ms,  1716011 100ns
HeapSort  堆排序算法  : 耗时:      359 ms,  3432022 100ns
MergeSort 归并排序算法: 耗时:     3260 ms, 32760210 100ns

第 13 次, 数据规模 650000
IntroSort 内省排序算法: 耗时:      172 ms,  1716011 100ns
ShellSort 希尔排序算法: 耗时:      390 ms,  3744024 100ns
QuickSort 快速排序算法: 耗时:      218 ms,  2184014 100ns
HeapSort  堆排序算法  : 耗时:      375 ms,  3588023 100ns
MergeSort 归并排序算法: 耗时:     3557 ms, 34476221 100ns

第 14 次, 数据规模 700000
IntroSort 内省排序算法: 耗时:      187 ms,  1872012 100ns
ShellSort 希尔排序算法: 耗时:      437 ms,  4368028 100ns
QuickSort 快速排序算法: 耗时:      218 ms,  2184014 100ns
HeapSort  堆排序算法  : 耗时:      406 ms,  4056026 100ns
MergeSort 归并排序算法: 耗时:     3838 ms, 37440240 100ns

第 15 次, 数据规模 750000
IntroSort 内省排序算法: 耗时:      202 ms,  2028013 100ns
ShellSort 希尔排序算法: 耗时:      468 ms,  4680030 100ns
QuickSort 快速排序算法: 耗时:      234 ms,  2340015 100ns
HeapSort  堆排序算法  : 耗时:      468 ms,  4524029 100ns
MergeSort 归并排序算法: 耗时:     4087 ms, 39936256 100ns

第 16 次, 数据规模 800000
IntroSort 内省排序算法: 耗时:      203 ms,  2028013 100ns
ShellSort 希尔排序算法: 耗时:      577 ms,  5772037 100ns
QuickSort 快速排序算法: 耗时:      250 ms,  2496016 100ns
HeapSort  堆排序算法  : 耗时:      484 ms,  4680030 100ns
MergeSort 归并排序算法: 耗时:     4368 ms, 41808268 100ns

第 17 次, 数据规模 850000
IntroSort 内省排序算法: 耗时:      234 ms,  2340015 100ns
ShellSort 希尔排序算法: 耗时:      561 ms,  5616036 100ns
QuickSort 快速排序算法: 耗时:      281 ms,  2652017 100ns
HeapSort  堆排序算法  : 耗时:      531 ms,  5304034 100ns
MergeSort 归并排序算法: 耗时:     4664 ms, 44772287 100ns

第 18 次, 数据规模 900000
IntroSort 内省排序算法: 耗时:      219 ms,  2184014 100ns
ShellSort 希尔排序算法: 耗时:      593 ms,  5616036 100ns
QuickSort 快速排序算法: 耗时:      297 ms,  2964019 100ns
HeapSort  堆排序算法  : 耗时:      561 ms,  5616036 100ns
MergeSort 归并排序算法: 耗时:     4914 ms, 47268303 100ns

第 19 次, 数据规模 950000
IntroSort 内省排序算法: 耗时:      249 ms,  2496016 100ns
ShellSort 希尔排序算法: 耗时:      624 ms,  6240040 100ns
QuickSort 快速排序算法: 耗时:      296 ms,  2964019 100ns
HeapSort  堆排序算法  : 耗时:      624 ms,  5772037 100ns
MergeSort 归并排序算法: 耗时:     5258 ms, 50388323 100ns

第 20 次, 数据规模 1000000
IntroSort 内省排序算法: 耗时:      281 ms,  2652017 100ns
ShellSort 希尔排序算法: 耗时:      702 ms,  7020045 100ns
QuickSort 快速排序算法: 耗时:      327 ms,  3120020 100ns
HeapSort  堆排序算法  : 耗时:      671 ms,  6708043 100ns
MergeSort 归并排序算法: 耗时:     5819 ms, 52572337 100ns

 

posted @ 2016-05-27 17:25  冬日之湖  阅读(292)  评论(0)    收藏  举报