系列文章目录
提示: 以下是其他排序算法的链接🔗
文章目录
- 系列文章目录
- 什么是计数排序?
提示:以下是本篇文章正文内容,下面案例可供参考
什么是计数排序?
计数排序(Counting Sort)是一种线性时间复杂度的排序算法,适用于待排序序列的取值范围较小的情况。计数排序的核心思想是统计每个元素出现的次数,然后根据统计结果将元素放回到正确的位置上。
计数排序的步骤如下:
- 统计每个元素出现的次数:遍历待排序序列,统计每个元素出现的次数,并存储在一个辅助数组中。
- 计算每个元素的累计次数:对于辅助数组,计算每个元素的累计次数,即前面所有元素出现的总次数。
- 根据累计次数将元素放回正确的位置:从后往前遍历待排序序列,根据元素的值在辅助数组中查找对应的累计次数,将元素放回到正确的位置上,并更新累计次数。
- 完成排序后,得到的序列就是有序的结果。
计数排序的时间复杂度为O(n+k),其中n是待排序序列的长度,k是待排序序列中元素的取值范围。计数排序的空间复杂度为O(n+k)。
需要注意的是,计数排序要求待排序序列的元素必须是非负整数(如果过有负数,必须处理为非负数),并且取值范围不能太大,否则会导致辅助数组过大。
代码模板(示例):
class Solution {
public int[] sortArray(int[] nums) {
countSort(nums);
return nums;
}
/**
* 计数排序
* O(N + k),k 为临时数组的大小
* 稳定
*/
public static void countSort(int[] arr) {
int min = arr[0];
int max = arr[0];
// 选出最大值和最小值
for (int i = 1; i < arr.length; i++) {
min = Math.min(min, arr[i]);
max = Math.max(max, arr[i]);
}
// 可能有负数,所以需要这样处理
int n = max - min + 1;
int[] count = new int[n];
// 遍历原数组,统计各个元素出现的次数
for (int val : arr) {
// 将元素映射为下标
int index = val - min;
// 统计数量
count[index]++;
}
// 将元素按照个数填回原数组
int index = 0;
for (int i = 0; i < n; i++) {
while (count[i] > 0) {// 有几个值填回去几个
int val = i + min;
arr[index++] = val;
count[i]--;
}
}
}
}