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,就会浪费很多空间,此时使用其他排序更好
- 不过这个排序还是有使用场景的,刷题时用到的比较多
- 总结:又到了暑假这个重要的冲刺阶段了,希望各位都坚持下去,有所收获