天天看點

線性時間排序 計數排序(Counting Sort)

基本思想:

我們已經學習過其他的排序算法,插入排序,歸并排序,快速排序,随機快速排序,堆排序等等。但是這些算法最快的也要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");
}
           

繼續閱讀