前篇講到對quicksort進行微調,使得它能有效支持大量重複數據的排序。算法
quicksort, merge sort, heap sort等都是「比較模型「的算法,其worst-case running time是不能小於nlgn的。這一點能夠由decision-tree (一個二叉樹)的葉子節點的個數來推出(由於worst-case屬於decision-tree中的最長路徑,因此只有當decision-tree平衡時,其worst-case 運行時間纔是最小的。此時能夠由樹的高度和葉子節點樹數量得出一個不等式,再利用n!的stirling公式近似,得出結論)。dom
而counting sort就是一種典型的」非比較模型「的算法,主要用於對取值範圍較小的整數進行排序。時間負載度是n+range,當range較小時,就是n。ui
首先對比下counting sort和上篇的quicksort2的運行時間:code
~/MyPro/Algorithms/sort $ ./counting_sort 1000000 100
start sorting ...
sorting finished!
====================================
counting sort
Sorting 1000000 elements
Time: 0s 42568us
The result is right !
====================================
~/MyPro/Algorithms/sort $ ./quicksort2 1000000 100
start sorting ...
sorting finished!
====================================
Randomized Quicksort
Sorting 1000000 elements
Time: 0s 193737us
The result is right !
====================================排序
而後,給出counting sort的主要代碼:ci
/** * function: counting_sort -- sort a[begin:end) of range [0, range-1] * **/ void counting_sort(int a[], int begin, int end, int range) { int aux_array_size = range; /* 0 -- range-1 */ int *aux = (int*)malloc_c(sizeof(int)*range); int *b = (int*)malloc_c(sizeof(int)*(end-begin)); int i, j; for (i=0; i<range; i++) { aux[i] = 0; } for (j=begin; j<end; j++) { aux[a[j]] += 1; } for (i=1; i<range; i++) { aux[i] = aux[i-1] + aux[i]; } for (j=end-1; j>=begin; j--) { b[aux[a[j]]-1] = a[j]; aux[a[j]] -= 1; } for (j=begin; j<end; j++) { a[j] = b[j]; } free(b); free(aux); }