計數排序 (Counting Sort)

來源:互聯網
上載者:User

原文: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之間的數位最好的演算法,但是它不適合按字母順序排序人名。但是,計數排序可以用在基數排序中的演算法來排序資料範圍很大的數組。

演算法的步驟如下:

  1. 找出待排序的數組中最大和最小的元素
  2. 統計數組中每個值為i的元素出現的次數,存入數組C的第i
  3. 對所有的計數累加(從C中的第一個元素開始,每一項和前一項相加) (記錄小於它的元素個數,用來計算它在整體整體中的排名)
  4. 反向填充目標數組:將每個元素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];

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.