排序算法⑧——計(jì)數(shù)排序

計(jì)數(shù)排序

計(jì)數(shù)排序的核心在于將輸入的數(shù)據(jù)值轉(zhuǎn)化為鍵存儲在額外開辟的數(shù)組空間中。作為一種線性時間復(fù)雜度的排序,計(jì)數(shù)排序要求輸入的數(shù)據(jù)必須是有確定范圍的整數(shù)。

1. 計(jì)數(shù)排序的特征

當(dāng)輸入的元素是 n 個 0 到 k 之間的整數(shù)時,它的運(yùn)行時間是 Θ(n + k)。計(jì)數(shù)排序不是比較排序,排序的速度快于任何比較排序算法。
由于用來計(jì)數(shù)的數(shù)組C的長度取決于待排序數(shù)組中數(shù)據(jù)的范圍(等于待排序數(shù)組的最大值與最小值的差加上1),這使得計(jì)數(shù)排序?qū)τ跀?shù)據(jù)范圍很大的數(shù)組,需要大量時間和內(nèi)存。例如:計(jì)數(shù)排序是用來排序0到100之間的數(shù)字的最好的算法,但是它不適合按字母順序排序人名。但是,計(jì)數(shù)排序可以用在基數(shù)排序中的算法來排序數(shù)據(jù)范圍很大的數(shù)組。
通俗地理解,例如有 10 個年齡不同的人,統(tǒng)計(jì)出有 8 個人的年齡比 A 小,那 A 的年齡就排在第 9 位,用這個方法可以得到其他每個人的位置,也就排好了序。當(dāng)然,年齡有重復(fù)時需要特殊處理(保證穩(wěn)定性),這就是為什么最后要反向填充目標(biāo)數(shù)組,以及將每個數(shù)字的統(tǒng)計(jì)減去 1 的原因。

2.算法步驟

  • 找出待排序的數(shù)組中最大和最小的元素
  • 統(tǒng)計(jì)數(shù)組中每個值為i的元素出現(xiàn)的次數(shù),存入數(shù)組C的第i項(xiàng)
  • 對所有的計(jì)數(shù)累加(從C中的第一個元素開始,每一項(xiàng)和前一項(xiàng)相加)
  • 反向填充目標(biāo)數(shù)組:將每個元素i放在新數(shù)組的第C(i)項(xiàng),每放一個元素就將C(i)減去1
countingSort.gif

3.代碼

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void
print_arr(int *arr, int n)
{
    int i;
    printf("%d", arr[0]);
    for (i = 1; i < n; i++)
        printf(" %d", arr[i]);
    printf("\n");
}

void
counting_sort(int *ini_arr, int *sorted_arr, int n)
{
    int *count_arr = (int *) malloc(sizeof(int) * 100);
    int i, j, k;
    for (k = 0; k < 100; k++)
        count_arr[k] = 0;
    for (i = 0; i < n; i++)
        count_arr[ini_arr[i]]++;
    for (k = 1; k < 100; k++)
        count_arr[k] += count_arr[k - 1];
    for (j = n; j > 0; j--)
        sorted_arr[--count_arr[ini_arr[j - 1]]] = ini_arr[j - 1];
    free(count_arr);
}

int main(int argc, char **argv)
{
    int n = 10;
    int i;
    int *arr = (int *) malloc(sizeof(int) * n);
    int *sorted_arr = (int *) malloc(sizeof(int) * n);
    srand(time(0));
    for (i = 0; i < n; i++)
        arr[i] = rand() % 100;
    printf("init_array: ");
    print_arr(arr, n);
    counting_sort(arr, sorted_arr, n);
    printf("sorted_array: ");
    print_arr(sorted_arr, n);
    free(arr);
    free(sorted_arr);
    return 0;
}

轉(zhuǎn)載于菜鳥教程


2020.11.18 11:45 深圳

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 計(jì)數(shù)排序 基本思想:不通過比較,計(jì)下每個元素的出現(xiàn)次數(shù),統(tǒng)計(jì)小于這個元素的個數(shù)N,將其放在N位。例如{7,6,2,...
    守敬閱讀 2,558評論 1 2
  • 初始計(jì)數(shù)排序 摘自漫畫算法: 計(jì)數(shù)排序是一種不基于元素比較,利用數(shù)組索引來確定元素的正確位置的。 假設(shè)數(shù)組中有20...
    花逝97閱讀 582評論 0 1
  • 前面說的那些排序算法,都是要通過比較來實(shí)現(xiàn)的。排序還能不通過比較來實(shí)現(xiàn)?是的,計(jì)數(shù)排序就是這么神奇。 一、排序思想...
    貪挽懶月閱讀 597評論 0 1
  • 計(jì)數(shù)排序是一種非比較的排序,這種方法思路大概是先算出待排序數(shù)據(jù)里面的數(shù)字分別出現(xiàn)多少次,然后再依據(jù)這個存放進(jìn)新的數(shù)...
    KPort閱讀 345評論 0 1
  • 題外話計(jì)數(shù)排序時間性能比之前的排序算法高,在實(shí)際中應(yīng)用較多,只需要O(n)時間即可完成排序。計(jì)數(shù)排序思想比較巧妙,...
    哪有歲月靜好閱讀 361評論 0 0

友情鏈接更多精彩內(nèi)容