1.核心思路
- 首先要找出max 和 min,最大值 - 最小值 + 1,就可以计算出数据在什么范围
- 然后创建计数数组大小,a[i] - min 在数组的相对位置计数 通过自然序列排序
- 然后把计数好的值,按照顺序依次放回原数组即可
动图解释,其实这个排序很简单,最主要就是 count[a[j] - min]++ 和 a[y++] = x + min;这两句核心代码,这个会了其他都是水到渠成
2.代码部分
void CountSort(int* a,int n)
{
//找出最大和最小值
int max = a[0], min = a[0];
for (int i = 0; i < n; i++)
{
if (max < a[i])
max = a[i];
if (min > a[i])
min = a[i];
}
//开辟相对计数空间大小
int range = max - min + 1;
int* count = calloc(range, sizeof(int));
if (count == NULL)
{
perror("count fail");
return;
}
//计数
for (int j = 0; j < n; j++)
{
count[a[j] - min]++;
}
//排序
int y = 0;
for (int x = 0; x < range; x++)
{
while (count[x]--)
{
a[y++] = x + min;
}
}
free(count);
//打印
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
}
- 时间复杂度是O(N + range),因为N代表数据个数;range 计数数组
- 空间复杂度是 O(range);
- 只适用于整形,且数据集中;但是排序速度特别快
- 不可能0 - 20数据居多,突然来个1000,就会浪费很多空间,此时使用其他排序更好
- 不过这个排序还是有使用场景的,刷题时用到的比较多
- 总结:又到了暑假这个重要的冲刺阶段了,希望各位都坚持下去,有所收获