經典演算法 計數排序演算法

2021-08-25 19:21:28 字數 1364 閱讀 7077

計數排序:

該演算法於2023年由 harold h. seward 提出。

它是乙個不需要比較的,類似於桶排序的線性時間排序演算法。該演算法是對已知數量範圍的陣列進行排序。其時間複雜度為o(n),適用於小範圍集合的排序。計數排序是用來排序0到100之間的數字的最

好的演算法。比如100萬學生參加高考,我們想對這100萬學生的數學成績(假設分數為0到100)做個排序。

基本思想:

對於給定的輸入序列中的每乙個元素x,確定該序列中值小於x的元素的個數 。一旦有了這個資訊,就可以將x直接存放到最終的輸出序列的正確位置上。它建立乙個長度為這個資料範圍的陣列c,c中每個元素記錄要排序陣列中對應記錄的出現個數。

下面以示例來說明這個演算法:

假設要排序的陣列為 a = 這裡最大值為3,最小值為0,那麼我們建立乙個陣列c,長度為4。然後一趟掃瞄陣列a,得到a中各個元素的總數,並保持到陣列c的對應單元中。比如0 的出現次數為2次,則 c[0] = 2;1 的出現次數為4次,則c[1] = 4。由於c 是以a的元素為下標的,所以這樣一做,a中的元素在c中自然就成為有序的了,這裡我們可以知道 順序為 0,1,3 (2 的計數為0)然後我們把這個在c中的記錄按每個元素的計數展開到輸出陣列b中,排序就完成了。

也就是 b[0] 到 b[1] 為0 b[2] 到 b[5] 為1 這樣依此類推。

這種排序演算法,依靠乙個輔助陣列來實現,不基於比較,演算法複雜度為 o(n) ,但由於要乙個輔助陣列c,所以空間複雜度要大一些,由於計算機的記憶體有限,所以這種演算法不適合範圍很大的數的排序。

上述為計數排序演算法的經典解法,不過這個解法並不是最優的,因為空間複雜度還應該可以優化,我們完全可以不要那個輸出的陣列b,直接對c進行排序。

演算法的步驟如下:

1.找出待排序的陣列中最大和最小的元素

2.統計陣列中每個值為i的元素出現的次數,存入陣列c的第i項

3.對所有的計數累加(從c中的第乙個元素開始,每一項和前一項相加)

4.反向填充目標陣列:將每個元素i放在新陣列的第c(i)項,每放乙個 元素就將c(i)減去1

測試**:

#include #include void print_arry(int *arr,int n) //列印陣列

free(count_arr);

} int main()

{ int n,i;

int *arr,*sorted_arr;

printf ("輸入陣列大小n:");

scanf ("%d", &n);

arr = (int *)malloc(sizeof(int) * n);

sorted_arr = (int *)malloc(sizeof(int) * n);

for (i = 0; i

經典演算法 計數排序

概述 計數排序是乙個非基於比較的排序演算法,該演算法於1954年由 harold h.seward 提出。它的優勢在於在對一定範圍內的集合排序時,它的複雜度為 n k 其中k是元素的範圍 快於任何比較排序演算法。計數排序本質上是通過計算無序集合中元素出現的次數來決定集合應該如何排序的。例如乙個陣列,...

經典演算法之計數排序

一 引言 計數排序假設 n個輸入元素中的每乙個都是介於 0 k的整數,此處 k為某個整數。當k等於o n 時,計數排序的執行時間為 n 二 基本思想 計數排序的基本思想就是對每乙個輸入元素x,確定小於x的元素個數。因此我們就可以直接把x放到最終輸出陣列中的相應位置上。例如 如果有 17個元素小於x,...

經典演算法之計數排序

一 引言 計數排序假設 n個輸入元素中的每乙個都是介於 0 k的整數,此處 k為某個整數。當k等於o n 時,計數排序的執行時間為 n 二 基本思想 計數排序的基本思想就是對每乙個輸入元素x,確定小於x的元素個數。因此我們就可以直接把x放到最終輸出陣列中的相應位置上。例如 如果有17個元素小於x,則...