任何比较排序(归并排序,插入排序等等)的时间复杂度在最坏的情况下都需要做Ω(n * lgn)次比较,而这里的的计数排序由于它不是基于比较排序的思路,所以它的复杂度不收这个限制,它的时间复杂度为Θ(n),为线性时间。同时,计数排序一个重要的性质就是它是稳定的,也就是说,对于两个相同的数来说,在输入数组中先出现的,在输出数组中也位于前面。
详细知识参考《算法导论》P109
----------------------------------------------------------代码如下------------------------------------------------------------
1 // 计数排序.cpp: 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 #include <vector> 7 8 using namespace std; 9 10 int COUNTING_SORT(vector<int> &A,vector<int> &B,int k)//A为输入数组,B为输出数组,A中放入元素都是在[0,k]之间的,当k = O(n)时,算法的时间复杂度是线性时间 11 { 12 int *C = new int[k + 1]{0};//C[0..k]提供临时存储空间 13 for (int i = 0; i < A.size(); i++) 14 { 15 if (!(A[i] >= 0 && A[i] <= k)) 16 { 17 cout << "输入数组中的元素有不在[ 0," << k << " ]之间的!"; 18 delete C; 19 return 0; 20 } 21 } 22 23 for (int i = 0; i < A.size(); i++) 24 C[A[i]] ++; 25 //现在C[i]的值表示A中值等于i的元素的个数 26 27 for (int i = 1; i <= k; i++) 28 C[i] += C[i - 1]; 29 //现在C[i]的值表示A中值小于或者等于i的元素的个数 30 31 for (int i = A.size() - 1; i >= 0; i--) 32 { 33 B[C[A[i]]-1] = A[i]; 34 C[A[i]]--; 35 } 36 delete C; 37 return 0; 38 } 39 40 41 int main() 42 { 43 vector<int> A = {2,5,3,0,2,3,0,3}; 44 for (auto c : A) 45 cout << c << ends; 46 cout << endl; 47 48 vector<int> B(8,0); 49 COUNTING_SORT(A, B, 5); 50 for (auto c : B) 51 cout << c << ends; 52 cout << endl; 53 return 0; 54 }
运行结果如下: