如果已知被排序的n个元素,值范围固定在在 "[0,k)"内],那么计数排序是最好的选择,它具有线性复杂度。
这个约束有些过强,有些时候,可以将不满足这个条件的转化一下:
比如 [-k, k)映射]到[0, 2k)等]。
再比如1/p的小树映射到p k-p等等。
下面上算法,主要走两遍:
首先建立k个桶
(1)扫描n个元素,增加对应桶中的计数
(2)从小到大扫描k个桶,计数非零则减一,然后顺序、依次输出。
源代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void countingSort(int* arr, int n, int k)
{
int i, idx;
int* buckets = NULL;
//Allocate Buckets
buckets = (int*)malloc(sizeof(int)*k);
if(!buckets)
{
return ;
}
memset(buckets, 0, sizeof(int)*k);
//Step1: Scan arr and put into bucket
for(i=0; i<n; i++)
{
buckets[arr[i]]++;
}
//Step2: Using buckets to sort
idx = 0;
for(i=0; i<k; i++)
{
while(buckets[i]--)
{
arr[idx++] = i;
}
}
}
int main()
{
int array[10] = {5,4,3,2,1,10,20,30,0,8};
int i;
int n;
n = sizeof(array) / sizeof(int);
countingSort(array, n, 100);
for(i=0; i<n; i++)
{
printf("%d ", array[i]);
}
printf("\n");
return 0;
}