📅  最后修改于: 2023-12-03 15:27:57.361000             🧑  作者: Mango
计数排序是一种非常快速的排序算法,它的核心思想在于统计每个元素出现的次数,然后根据这个统计结果将元素排好序。计数排序适用于数据范围比较小的情况,时间复杂度为$O(n+k)$,其中$n$为待排序序列长度,$k$为元素取值范围。
以一个整型数组为例,代码如下:
public static int[] countingSort(int[] arr) {
if (arr == null || arr.length < 2) {
return arr;
}
int[] count = new int[10];
for (int i = 0; i < arr.length; i++) {
count[arr[i]]++;
}
for (int i = 1; i < count.length; i++) {
count[i] += count[i - 1];
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[--count[arr[i]]] = arr[i];
}
return res;
}
上述代码实现了一个简单的计数排序算法,其中count
数组用于统计每个数字出现的次数,res
数组用于存放排序后的结果。时间复杂度为$O(n+k)$,空间复杂度为$O(k)$。
在实际应用中,可以通过以下方式优化计数排序算法:
数组扩容:当元素取值范围$k$较大时,可以先统计元素出现次数,再按照次数创建一个新的数组。这样可以减小空间复杂度,同时也可以大幅减少时间复杂度。
两趟扫描:统计元素出现次数的过程可以分为多次遍历,减少数组扫描次数。
public static int[] countingSort(int[] arr) {
if (arr == null || arr.length < 2) {
return arr;
}
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
max = Math.max(max, arr[i]);
}
int[] count = new int[max + 1];
for (int i = 0; i < arr.length; i++) {
count[arr[i]]++;
}
for (int i = 1; i < count.length; i++) {
count[i] = count[i] + count[i - 1];
}
int[] res = new int[arr.length];
for (int i = arr.length - 1; i >= 0; i--) {
res[--count[arr[i]]] = arr[i];
}
return res;
}
上面的代码实现了一个优化版的计数排序算法,时间复杂度为$O(n+k)$,空间复杂度为$O(k)$。它避免了数组扫描次数过多的情况,同时也减小了空间复杂度。
计数排序适用于数据范围比较小的情况,如桶排序、基数排序等算法的基础。在一些计算机视觉领域、排序算法等应用中,计数排序也被广泛地使用。