計數排序算法


計數排序(Counting sort)是一種穩定的線性時間排序算法。計數排序使用一個額外的數組C,其中第i個元素是待排序數組A中值等於i的元素的個數。然后根據數組C來將A中的元素排到正確的位置。

本文地址:http://www.cnblogs.com/archimedes/p/counting-sort-algorithm.html,轉載請注明源地址。

計數排序的特征

當輸入的元素是 n 個 0 到 k 之間的整數時,它的運行時間是 Θ(n + k)。計數排序不是比較排序,排序的速度快於任何比較排序算法。

由於用來計數的數組C的長度取決於待排序數組中數據的范圍(等於待排序數組的最大值與最小值的差加上1),這使得計數排序對於數據范圍很大的數組,需要大量時間和內存。例如:計數排序是用來排序0到100之間的數字的最好的算法,但是它不適合按字母順序排序人名。但是,計數排序可以用在基數排序中的算法來排序數據范圍很大的數組。

通俗地理解,例如有10個年齡不同的人,統計出有8個人的年齡比A小,那A的年齡就排在第9位,用這個方法可以得到其他每個人的位置,也就排好了序。當然,年齡有重復時需要特殊處理(保證穩定性),這就是為什么最后要反向填充目標數組,以及將每個數字的統計減去1的原因。

算法的步驟如下:

  1. 找出待排序的數組中最大和最小的元素

  2. 統計數組中每個值為i的元素出現的次數,存入數組C的第i

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

  4. 反向填充目標數組:將每個元素i放在新數組的第C(i)項,每放一個元素就將C(i)減去1

對於數據2 5 3 0 2 3 0 3程序執行的過程如下圖所示:

算法實現

C代碼如下:

// Completed on 2014.10.10 20:37
// Language: C99
//
// 版權所有(C)codingwu   (mail: oskernel@126.com) 
// 博客地址:http://www.cnblogs.com/archimedes/
#include<stdio.h>
#include<stdlib.h>
int* countingSort(int *a, int n, int k)
{
    int c[k + 1], i, value, pos;
    int *b = (int *)malloc(n * sizeof(int));
    for(i = 0; i <= k; i++)  //初始化
        c[i] = 0;
    for(i = 0; i < n; i++)
        c[a[i]]++;            
    for(i = 1; i <= k; i++)
        c[i] = c[i] + c[i - 1];
    for(i = n - 1; i >= 0; i--) {
        value = a[i];
        pos = c[value];
        b[pos - 1] = value;
        c[value]--;
    }
    return b;
}
int maxArr(int *a, int n)  //返回數組中最大的元素
{
    int i, max;
    max = a[0];
    i = 1;
    int *p;
    p = a + 1;
    while(i++ < n) {
        if(max < *p) 
            max = *p;
        p++;
    }
    return max;
}
int main()
{
    int a[] = {2, 5, 3, 0, 2, 3, 0, 3};
    int N, max;
    N = sizeof(a) / sizeof(a[0]);
    max = maxArr(a, N);
    int *p = countingSort(a, N, max);
    for(int k = 0; k < N; k++)
        printf("%d ", p[k]);
    printf("\n");
    free(p);
    return 0;
}

對代碼有疑惑的可以參考《C語言指針傳遞詳解

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM