1. 程式人生 > >【演算法導論】計數排序

【演算法導論】計數排序

計數排序假設n個輸入元素中的每一個都是介於0到k之間的整數,此處k為某個整數。

計數排序的基本思想就是對每一個輸入元素x,確定出小於x的元素個數。有了這一資訊,就可以把x直接放到它在最終輸出陣列中的位置上。例如,如果有17個元素小於x,則x就屬於第18個輸出位置。當有幾個元素相同時,這個方案要略作修改,因為不能把它們放在同一個輸出位置上。

在計數排序演算法的程式碼中,我們假定輸入是個陣列A[1...n],另外還需要兩個陣列:存放排序結果的B[1...n],以及提供臨時儲存區的C[0...k]。

#include <iostream>
using namespace std;

#define len 8

void CountSort(int A[], int B[], int k)
{
	int *C=new int[k+1];
	for(int i=0; i<=k; i++)
		C[i]=0;

	//C[i]包含等於i的元素個數
	for(i=0; i<len; i++)
		C[A[i]]++;

	//C[i]包含小於等於i的元素個數
	for(i=1; i<=k; i++)
		C[i]+=C[i-1];

	for(i=len-1; i>=0; i--)//從後往前處理A中的元素,以保證穩定性
	{
		B[C[A[i]]-1]=A[i];//C[A[i]]表示A[i]在B中的位置,但B[i]從0開始,不是從1開始,所以要減1
		C[A[i]]--;//可處理元素重複問題

	}
}

void main()
{
	int a[len]={2,5,3,0,2,3,0,3};
	int *b=new int[len];
	CountSort(a, b, 5);

	for(int i=0; i<len; i++)
		cout<<b[i]<<" ";
	cout<<endl;

}



計數排序執行時間O(n),計數排序不是基於比較的排序演算法。

計數排序的一個重要性質就是它是穩定的:具有相同值的元素在輸出陣列中的相對次序與它們在輸入陣列中的次序相同。亦即,兩個相同數之間的順序是這樣來規定的,即在輸入陣列中先出現的,在輸出陣列中也位於前面。之所以說計數排序的穩定性非常重要,是因為計數排序經常用作基數排序演算法的一個子過程。計數排序的穩定性對基數排序的正確性來說,是非常關鍵的。

保證計數排序穩定的重要語句是:for(i=len-1; i>=0; i--)//從後往前處理A中的元素,以保證穩定性。