计数排序详解

如有错误,感谢不吝赐教、交流

算法原理

计数排序假设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),使用了额外空间。

ps:计划每日更新一篇博客,今日2023-04-25,日更第九天。
昨日更新:
快速排序详解
堆排序详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值