如有错误,感谢不吝赐教、交流
文章目录
算法原理
计数排序假设n个输入元素中的每一个都是在0到k区间内的一个整数,其中k为某个整数。当k=O(n)时,排序的运行时间为 O(n)。
计数排序的基本思想是:
对每一个输人元素x,确定小于 x的元素个数。利用这一信息,就可以直接把x放到它在输出数组中的位置上了。
例如,如果有 17 个元素小于 x,则就应该在第 18 个输出位置上。
注意:当有几个元素相同时,这一方案要略做修改。因为不能把它们放在同一个输出位置上。使用逆序遍历输出的方式解决。
核心
统计某个数字应该出现的位置,不是基于比较交换排序。
伪代码实现
在计数排序算法的代码中,假设输人是一个数组 A[1…n],A.length=n。我们还需要两个数组:B[1…n]存放排序的输出,C[0…k]提供临时存储空间。
Java完整代码实现
public class CountingSort {
public static void countingSort(int [] a, int [] b, int k) {
int [] c= new int[k + 1]; // c是count数组,用于计数,下标表示范围从0到k的值
// 遍历a数组计数,a中每出现一个值,c中以这个值为下标的值加1,表示该值在a中出现几次
for (int i = 0; i < a.length; i++) {
c[a[i]] = c[a[i]] + 1;
}
// 累加c数组,解决计数排序的不稳定问题
// 累加后c数组的值代表以当前c的下标m,在b中出现的位置下标是c[m]
for (int i = 1; i <= k; i++) {
c[i] = c[i] + c[i - 1];
}
// 逆序遍历数组a,根据累加后的数组c将a中每个元素正确填入b中正确的位置
for (int i = a.length - 1; i >= 0; i--) {
b[c[a[i]] - 1] = a[i]; // 注意这里数字下标是从0开始的,所以讲c[a[i]]减一
c[a[i]] = c[a[i]] - 1;
}
}
public static void main(String[] args) {
int[] a = {2, 5, 3, 0, 2, 3, 0, 3};
int[] b = new int[a.length];
int k = 5; // a数组中的最大值
countingSort(a, b, k);
for (int n :
b) {
System.out.print(n + " ");
}
}
}
总结
时间复杂度为O(n),空间复杂度为O(n),使用了额外空间。