常用排序之計數排序

2021-08-17 06:47:11 字數 1674 閱讀 8770

計數排序是一種非比較排序演算法。計數排序假設n個輸入元素中的每乙個都是在0到k區間內的乙個整數,其中k為某個整數。計數排序是穩定的。

基本思想

對每乙個輸入元素x,確定小於x的元素個數。利用這一資訊,就可以直接把x放到它在輸出陣列中的位置上了。例如,如果有17個元素小於x,則x就應該在第18個輸出位置上。當有幾個元素相同時,這一方案要修改,因為不能把它們放在同乙個輸出位置上。

實現

在計數排序演算法的**中,假設輸入時乙個陣列a[1..n],a.length=n。我們還需要兩個陣列:b[1..n]存放排序的輸出,c[0..k]提供臨時儲存空間。

下面是偽**:

1  let c[0..k]be a new array

2 for i=0 to k

3 c[i] = 0

4 for j=1 to a.length

5 c[a[j]] = c[a[j]] + 1

6 for i=1 to k

7 c[i] = c[i] + c[i-1]

8 for j=a.length down to 1

9 b[c[a[j]]] = a[j]

10 c[a[j]] = c[a[j]]-1

對於乙個陣列a=;

執行完2-3行以後陣列c的值全被置為0;第4-5行是統計陣列a中每個元素出現的個數;

第6-7行是通過加總計算確定對每乙個元素i=0...k,有多少元素是小於或等於i的;

最後8-10行把每個元素 a[j] 放到它在陣列b中的正確位置上。如果所有元素n個元素都是互異的,那麼當第一次執行第10行時,對每乙個 a[j] 值來說,c[a[j]] 就是 a[j] 在輸出陣列中的最終正確位置。這是因為共有 c[a[j]] 個元素小於或等於 a[j]。因為所有的元素並不都是互異的,所以,我們每將乙個值 a[j] 放入陣列b中以後,都要將 c[a[j]] 的值減1。這樣,當遇到下乙個值等於a[j] 的輸入元素時,該元素可以直接被放到輸出陣列中 a[j] 的前乙個位置上。

時間複雜度

計算2-3行的for迴圈所花時間 θ(k)

計算4-5行的for迴圈所花時間 θ(n)

計算6-7行的for迴圈所花時間 θ(k)

計算8-10行的for迴圈所花時間 θ(n)

總的時間代價為 θ(k+n)

在實際工作中,當 k=θ(n)時,我們一般採用計數排序,這時的執行時間為 θ(n)。

下面是**實現:

#include#includeusing namespace std;

#define maxn 8

int a[maxn] = ;

int b[maxn];

void count_sort(int k,int a_size)

for (i = 1; i < k; i++)

c[i] = c[i] + c[i - 1];

for (i = a_size-1; i >= 0; i--)

delete c;

}int main()

排序演算法之計數排序

今在學習中,遇到計數排序演算法,雖然其對待排序的序列要求嚴格,但對於符合條件的序列來說,其時間複雜度很小。故列於此,僅為學習記憶。參考資料 對於僅由大寫字母 或小寫字母 構成的無序序列,可採用下面演算法進行排序。該演算法不在序列的每個元素間進行比較,而是使用了乙個額外的help整型字串來記錄每個元素...

線性排序之 計數排序

counting sort適用於排列分布比較集中的資料,即最大值和最小值相差不會太大,具體這個差在多少合適,還是以後值得我思考的問題?計數排序的演算法思想是需要分配3個陣列,original,counter original counter i counter i counter i 1 即計數為小...

演算法 排序之計數排序

最近想到演算法導論中的計數排序,看看理解的怎麼樣試著講講自己的理解。1 思想 計數排序 是 線性時間的 排序演算法,時間複雜度為o n 雖然有一定的侷限性。但是還是很好的一種演算法。用2個陣列進行額外的儲存資訊,陣列 c 是對 資料中值相同的 記錄下來,以便後面查閱 b 是輸出的有序陣列,再將有序的...