原文:wiki : http://en.wikipedia.org/wiki/Counting_sort
http://zh.wikipedia.org/wiki/%E8%AE%A1%E6%95%B0%E6%8E%92%E5%BA%8F
計數排序(Counting sort)是一種穩定的排序演算法。計數排序使用一個額外的數組C,其中第i個元素是待排序數組A中值等於i的元素的個數。然後根據數組C來將A中的元素排到正確的位置。
計數排序的特徵
當輸入的元素是 n 個 0 到 k 之間的整數時,它的已耗用時間是 Θ(n + k)。計數排序不是比較排序,排序的速度快於任何比較排序演算法。
由於用來計數的數組C的長度取決於待排序數組中資料的範圍(等於待排序數組的最大值與最小值的差加上1),這使得計數排序對於資料範圍很大的數組,需要大量時間和記憶體。例如:計數排序是用來排序0到100之間的數位最好的演算法,但是它不適合按字母順序排序人名。但是,計數排序可以用在基數排序中的演算法來排序資料範圍很大的數組。
演算法的步驟如下:
- 找出待排序的數組中最大和最小的元素
- 統計數組中每個值為i的元素出現的次數,存入數組C的第i項
- 對所有的計數累加(從C中的第一個元素開始,每一項和前一項相加) (記錄小於它的元素個數,用來計算它在整體整體中的排名)
- 反向填充目標數組:將每個元素i放在新數組的第C(i)項,每放一個元素就將C(i)減去1
In pseudocode, this may be expressed as follows:
''' calculate histogram: '''# allocate an array Count[0..k] ; THEN# initialize each array cell to zero ; THENfor each input item x: increment Count[key(x)] ''' calculate starting index for each key: '''total = 0for i = 0, 1, ... k: oldCount = Count[i] Count[i] = total total = total + oldCount ''' copy inputs into output array in order: '''# allocate an output array Output[0..n-1] ; THENfor each input item x: Output[Count[key(x)]] = x decrement Count[key(x)]return Output
After the first for loop, Count[i] stores the number of items with key equal to i.After the second for loop, it instead stores the number of items with key less than i, which is the same
as the first index at which an item with keyi should be stored in the output array. Throughout the third loop,Count[i] always stores the next position in the output array into which an item with key i should be
stored, so each item is moved into its correct position in the output array.
The relative order of items with equal keys is preserved here; i.e., this is a stable sort.
我寫的代碼: (最新修改 2013-6-30)
/* * 計數排序: 穩定的排序 * huntinux * 13-6-18 * */#include <stdio.h>#include <malloc.h>void counting_sort(int *a, int n){ int *count, *tmparr; int i; count = malloc(sizeof(int) * n); if(!count) perror("malloc"); for(i = 0; i < n; i++) count[i] = 0; for(i = 0; i < n; i++) count[a[i]]++; for(i = 1; i < n; i++) count[i] += count[i-1]; tmparr = malloc(sizeof(int) * n); if(!tmparr) perror("malloc"); for(i = 0; i < n; i++) tmparr[i] = 0; for(i = n-1; i >= 0; i--) //這裡讓i從n-1開始,是保證在數字相等的情況下,預設靠前的數字要排在前面。(保證穩定排序) tmparr[--count[a[i]]] = a[i]; for(i = 0; i < n; i++) a[i] = tmparr[i]; free(count); free(tmparr);}void print_arr(int *a, int n, char *msg){ int i; if(msg) printf("%s\n", msg); for(i = 0; i < n; i++) printf("%d\t", a[i]); printf("\n");}int main(){ int a[15] = {8, 4 , 2, 6, 3, 1, 9, 3, 5, 7, 1, 9, 0, 2, 5}; print_arr(a, 15, "before sorting:"); counting_sort(a, 15); print_arr(a, 15, "after sorting:"); return 0;}注意下面的代碼是保證穩定排序的關鍵:
for(i = n-1; i >= 0; i--) //這裡讓i從n-1開始,是保證在數字相等的情況下,預設靠前的數字要排在前面。(保證穩定排序)tmparr[--count[a[i]]] = a[i];