基本思想:
我們已經學習過其他的排序算法,插入排序,歸併排序,快速排序,隨機快速排序,堆排序等等。但是這些算法最快的也要O(nlgn)。如何做到線性時間的排序呢?我們常說,空間和時間代價可以轉換。我們可以利用犧牲時間來獲取空間,也可以犧牲空間來獲取時間。計數排序就是這樣一種犧牲存儲空間來獲取更快時間的一種方法。
定義一個數組C,C的大小爲K+1,K是輸入數列中的最大數M;數組A中爲要排序的整數。
1.數組初始化爲0;
2.將C[A[i]]++;
3.C[i]+=C[i-1];(此時,C[A[i]]表示整數在排序之後應該在數列的位置);
4.將數放入數組B的對應位置,B則表示完成排序之後的數組。
我們可以發現,這個算法花費的時間是O(k+n)爲線性時間;當K太大是,此方法便不可用,因爲要開闢一個足夠大的數組。此外,這是一個穩定的排序。
代碼實現:
#include "iostream"
#include<algorithm>
#include<stdio.h>
void Counting_sort(int *A, int *B, int k, int arry_size) {
int C[k+1],i,j,pos,value;//對於C/C++來說,這裏會報錯,因爲無法動態的分配數組。
//要給數組指定一個確定的大小,而且還要滿足初始條件。
for (i = 0; i < 100; i++) {
C[i] = 0;
}
for (i = 0; i < arry_size; i++) {
C[A[i]]++;
}
for (i = 1; i < 100; i++) {
C[i] += C[i - 1];//C[A[i]]表示整數A[i]應該在排序中的位置
}
for (i = arry_size - 1; i >= 0; i--) {//倒敘處理,主要是爲了排序的穩定性
value = A[i];
pos = C[value];
B[pos - 1] = value;
C[value]--;//這一步,主要是考慮到了有相等情況。
}
}
int main() {
int A[8] = { 2, 5, 3, 0, 2, 3, 0, 3 }, B[8], i;
Counting_sort(A, B, 5, 8);
for (i = 0; i <= 7; i++)
{
printf("%d ", B[i]);
}
printf("\n");
}