任何比較排序在最好狀況下都要通過Ω(nlgn),即比較排序的下界爲Ω(nlgn)。ios
合併排序和堆排序都是漸進最優的。算法
要突破Ω(nlgn),就要進行非比較排序。計數排序、基數排序和桶排序都有非比較的一些操做來肯定排序順序,它們能夠達到線性運行時間。數組
計數排序法:spa
計數排序的基本思想是對每個輸入元素x,肯定出小於x的元素個數。有了這個信息就能夠把x直接放到他在最終輸出數組中的位置上。code
計數排序適用於小範圍集合的排序。它的複雜度爲Ο(n+k)(其中k是整數的範圍),快於任何比較排序算法。 可是當O(k)>O(n*log(n))的時候其效率反而不如基於比較的排序。orm
代碼以下:blog
#include <iostream> #include <limits.h> //輸入 A,輸出B void count_sort(int A[], int B[], int nLen) { //1.找出待排序的數組中最大和最小的元素 int k = INT_MIN; for (int i = 0; i < nLen; i++) { if (A[i] > k) { k = A[i]; } } //=============== int *C = new int [k];//統計的暫存數組 //初始化C for (int i = 0; i < k; i ++) { C[i] = 0; } //2.統計數組中每一個值爲i的元素出現的次數,存入數組C的第i項 //統計j的次數 for (int j = 0; j < k; j++){ C[A[j]] = C[A[j]] + 1;//統計A[j]出現了多少次 } //3.對全部的計數累加(從C中的第一個元素開始,每一項和前一項相加) for (int i = 0; i < k; i++) { C[i] = C[i] + C[i-1];//對於給定的輸入序列中的每個元素x,肯定該序列中值小於x的元素的個數 } //4.反向填充目標數組:將每一個元素i放在新數組的第C(i)項,每放一個 元素就將C(i)減去1 //逆向遍歷源數組(保證穩定性),根據計數數組中對應的值填充到先的數組中 for (int j = nLen; j>=0; j++) { B[C[A[j]]] = A[j]; C[A[j]] = C[A[j]] -1; } delete[] C; } int main() { int a[] = {5,9,3,9,10,9,2,4,13,10}; const size_t sz = sizeof(a)/sizeof(a[0]); for (int i = 0; i < sz; i++ ) { std::cout << a[i] << " "; } }
基數排序:排序
基數排序是首先按最低有效位數字進行排序的,它從低位到高位進行排序。它是一種穩定性的算法。it