算法精髓
-遍历待排序数组,找出最大值与最小值,并计算其差值。
创建临时数组,大小为其差值。
再次遍历原数组,对遍历到的每一个值在临时数组中加一,记录原数组中该值出现了n次。
将临时数组中不为0的值从小到大加上最小值输出n次。
算法实现
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
//计数排序
void CountSort(int* a, int len)
{
assert(a);
//通过max和min计算出临时数组所需要开辟的空间大小
int max = a[0], min = a[0];
for (int i = 0; i < len; i++) {
if (a[i] > max)
max = a[i];
if (a[i] < min)
min = a[i];
}
//使用calloc将数组都初始化为0
int range = max - min + 1;
int* b = (int*)calloc(range, sizeof(int));
if (b == NULL)return;
//使用临时数组记录原始数组中每个数的个数
for (int i = 0; i < len; i++) {
//注意:这里在存储上要在原始数组数值上减去min才不会出现越界问题
b[a[i] - min] += 1;
}
int j = 0;
//根据统计结果,重新对元素进行回收
for (int i = 0; i < range; i++) {
while (b[i]--) {
//注意:要将i的值加上min才能还原到原始数据
a[j++] = i + min;
}
}
//释放临时数组
free(b);
b = NULL;
}
//打印数组
void PrintArray(int* a, int len)
{
for (int i = 0; i < len; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
int main()
{
int a[] = { 3, 4, 3, 2, 1, 2, 6, 5, 4, 7 };
CountSort(a, sizeof(a) / sizeof(int));
PrintArray(a, sizeof(a) / sizeof(int));
system("pause");
return 0;
}
算法分析:
时间复杂度:O(n)
空间复杂度:O(n)
算法局限
- 排序元素为整数
- 元素值在一定范围内且分布集中