计数排序 (Count Sort)

简介:

计数排序(Count Sort)是一个非基于比较的排序算法,于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。

步骤:

(1) 初始化一个计数数组,大小是原数组中的最大的数。
(2) 遍历原数组,遇到一个数就在计数数组对应的位置上加一。例如:遇到5,就将计数数组第五个位置的数加一。
(3) 遍历计数数组, 如第 i 的元素上值为 value, 则添加 value 个值为 i 的元素到原数组上,覆盖原数组的元素。

复杂度:

时间:O(n + k),n是输入数组长度,k是最大的数的大小。
空间:O(n + k),n是输入数组长度,k是最大的数的大小。

图解过程:

C语言版代码如下:

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

// 返回长为 size 的数组 array 中最大的元素的值
int getMaxValue(int array[], int size){
    int maxValue = 0;
    for (int i = 0; i < size; i++) {
        if (array[i] > maxValue) {
            maxValue = array[i];
        }
    }
    return maxValue;
}

// 对长为 size 的数组 array进行计数排序
void countSort(int array[], int size){
    // 获取数组中最大的元素的值
    int maxValue = getMaxValue(array, size);

    // 创建一个数组做计数用, 且每个元素初始值为 0
    int *countArray = calloc(maxValue, sizeof(int));

    // 计数过程: 遍历原数组, 如果值与计数数组的下标相同+1,则计数数组该下标上的元素值加1
    for (int i = 0; i < size; i++) {
        // array 上值为 5 的元素,应该放在 countArray 第 5 个元素上,即下标为 4.
        countArray[array[i] - 1]++;
    }

    // 计数完毕,遍历计数数组,结果输出到原数组上.
    for (int k = 0, j = 0; k < maxValue && j <= size; k++) {
        while (countArray[k] > 0) {
            // 第 k 位表示的数值为 k + 1.
            array[j] = k + 1;
            countArray[k]--;
            j++;
        }
    }
}

int main(int argc, const char * argv[]) {

    int array[10] = {5,1,7,3,9,3,7,5,6,3};

    countSort(array, 10);

    return 0;
}

//打印结果:
//原数组: 5 1 7 3 9 3 7 5 6 3
//计数数组:
//0 0 0 0 1 0 0 0 0
//1 0 0 0 1 0 0 0 0
//1 0 0 0 1 0 1 0 0
//1 0 1 0 1 0 1 0 0
//1 0 1 0 1 0 1 0 1
//1 0 2 0 1 0 1 0 1
//1 0 2 0 1 0 2 0 1
//1 0 2 0 2 0 2 0 1
//1 0 2 0 2 1 2 0 1
//1 0 3 0 2 1 2 0 1
//计数排序后: 1 3 3 3 5 5 6 7 7 9

你可能感兴趣的:(计数排序 (Count Sort))