桶排序 — 计数排序和基数排序

这篇具有很好参考价值的文章主要介绍了桶排序 — 计数排序和基数排序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

计数排序
int类型数组,其中存的是员工的年龄。比如说16 - 150。对于这样的数据来讲,数据状况是受限的。此时如果将数组从小到大进行排序,该如果实现?
这个实现很简单,实现一个统计数组范围从 0 ~ 150,新数组下标对应着老数组的值,新数组的值对应着老数组相同值的个数,遍历新数组找到个数不为0的元素,按顺序放回到老数组即可。整体时间复杂度O(N)。

public void countSort(int[] arr) {
            int max = Integer.MIN_VALUE;
            //选出最大值
            for (int i = 0; i < arr.length; i++) {
                Math.max(max, arr[i]);
            }
            //数组长度取年龄最大值 + 1
            int[] count = new int[max + 1];

            for (int j = 0; j < arr.length; j++) {
                count[arr[j]]++;
            }

            int i = 0;
            for (int k = 0; k < count.length; k++) {
                while (count[k]-- > 0) {
                    arr[i++] = k;
                }
            }
        }

这种排序称为计数排序,计数排序所用的思想是桶排序的思想,桶就是容器的意思,题中的年龄就是桶。

这样来看,从排序特征上来分大致可分为两类:不基于比较的排序和比较排序。其中桶排序就是不基于比较的一个。
计数排序不是基于比较,根据年龄,放入不同的桶中,最后从桶中获取,一个比较行为都没有。
不基于比较的排序,一定是数据范围比较特殊。所以,不基于比较的排序的扩展性相较于基于比较的排序来讲,可扩展性比较小,因为基于比较的排序实现了一个对数器之后,所有的基于比较的排序都可以用,而不基于比较的不可以。需要根据具体的样本特征来具体的分析。

基数排序
基数排序对数据范围的约束大概在非负的,用十进制表示的数(负的找到最小值,数组整体加成正数也行)。
假设int[] {103,13,27,25,17,9}。
先将数组中最大值103找出来,算出十进制的位数(几次能将10除完),得出是3。
将其余元素不满3位的高位补0,补充之后是{103,013,027,025,017,009}。
准备0 ~ 9一共10个桶,数组从左往右,根据个位数放进对应下标的桶中。
桶排序 — 计数排序和基数排序
放入后,从0桶开始,依次倒出并清空桶(根据个位数排序)。
桶排序 — 计数排序和基数排序
根据十位数大小,再次放入桶中。
桶排序 — 计数排序和基数排序
再次倒出桶中元素,并清空桶。
桶排序 — 计数排序和基数排序
第三次,将百位数放入桶中后再次倒出。
桶排序 — 计数排序和基数排序
倒出后,数组有序{009,013,017,025,027,103}
代码实现:
代码中,没有使用队列的方式来创建桶,而是用了另一种方式。文章来源地址https://www.toymoban.com/news/detail-465329.html

 public static void RadixSort(int[] arr) {
            if (arr == null || arr.length < 2) {
                return;
            }
            radixSort(arr, 0, arr.length - 1, maxbits(arr));
        }

        // L。。。R进行排序
        public static void radixSort(int[] arr, int L, int R, int digit) {
            final int radix = 10;
            int i = 0, j = 0;
            // 有多少个数准备多少个辅助空间
            int[] help = new int[R - L + 1];
            for (int l = 1; l < digit; l++) {
                int[] count = new int[radix];

                for (i = L; i <= R; i++) {
                    j = getDigit(arr[i], l);
                    //统计每个数字出现的次数
                    count[j]++;
                }
                //求出所有次数的前缀和
                for (i = 1; i < radix; i++) {
                    count[i] = count[i] + count[i - 1];
                }
                //从尾向前遍历
                for (i = R; i >= L; i--) {
                    //再次获取当前数的各位十位百位数。
                    j = getDigit(arr[i], l);
                    //count[j] 代表  <= arr[i]的数当前一共出现了 count[j]次
                    //count[j] - 1,代表了当前arr[i]在help数组中的位置
                    //因为是从右向前遍历,所以代表当前数要落在<= arr[i]的那些count[j]中的最右边 
                    help[count[j] - 1] = arr[i];
                    //对应位置数量 - 1
                    count[j]--;
                }

            }
        }

        public static int maxbits(int[] arr) {

            int max = Integer.MIN_VALUE;
            //找到数组中最大值
            for (int i = 0; i < arr.length; i++) {
                Math.max(max, arr[i]);
            }
            int res = 0;
            //根据最大值/10,找到十进制位数
            while (max != 0) {
                res++;
                max /= 10;
            }
            return res;
        }

        //d = 1,2,3 求出x的个位十位百位
        public static int getDigit(int x, int d) {
            return ((x / ((int) Math.pow(10, d - 1))) % 10);
        }

到了这里,关于桶排序 — 计数排序和基数排序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 常见排序算法(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序,计数排序,基数排序,桶排序)

    1. 排序 :所谓排序,就是使一串记录,按照其中的某个或某些的大小, 递增或递减 的排列起来的操作 2. 稳定性 :假定在待排序的记录序列中,存在多个具有相同的的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,

    2024年04月23日
    浏览(42)
  • Python篇——数据结构与算法(第四部分:希尔排序及其讨论、计数排序、桶排序、基数排序)

    希尔排序(shell sort)是一种分组插入排序算法 首先取一个整数d1=n/2,将元素分为d1个组,每组相邻两元素之间距离为d1,在各 组内 进行直接插入排序 取第二个整数d2=d1/2,重复上述分组排序过程,知道di=1,即所有元素在同一组内进行直接插入排序。 希尔排序每趟并不使某些

    2024年02月07日
    浏览(42)
  • 【Python排序算法】一文掌握十大排序算法,冒泡排序、插入排序、选择排序、归并排序、计数排序、基数排序、希尔排序和堆排序

    目录 1 冒泡排序(Bubble Sort) 2 插入排序(Insertion Sort) 3 选择排序(Selection Sort) 4. 快速排序(Quick Sort) 5. 归并排序(Merge Sort) 6 堆排序 (Heap Sort) 7 计数排序 (Counting Sort) 8 基数排序 (Radix Sort) 9 希尔排序(Shell Sort) 10 桶排序     1 冒泡排序(Bubble Sort)        冒泡排序

    2024年02月08日
    浏览(55)
  • LeetCode 周赛 342(2023/04/23)容斥原理、计数排序、滑动窗口、子数组 GCB

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问。 大家好,我是小彭。 前天刚举办 2023 年力扣杯个人 SOLO 赛,昨天周赛就出了一场 Easy - Easy - Medium - Medium 的水场,不得不说 LeetCode 是懂礼数的 😁。 接下来,请你跟着小彭的思路,一步步将问题做难,

    2023年04月24日
    浏览(37)
  • Java 中数组的排序(基本类型,对象类型)

    前言: 本文主要针对的是 Java 自带的排序函数/接口 实现 Comparable 接口中的 compareTo 函数或实现 Comparator 接口中的 compare 函数 两者存在使用上的区别,大体而言,Comparable 接口是为类服务,Comparator 接口是为 sort (Arrays.sort / Collections.sort)方法服务 基本类型存在很多种,这里举

    2024年02月07日
    浏览(34)
  • 考研算法33天:基数排序 【基数排序】

    我们前一天写了一道桶排序,今天开始看它的进化版:基数排序,为啥会有这个算法呢?因为我们桶排序有一部是需要统计每个数字出现的次数因此需要开一个相对大的数组 但是就像快速排序这道题,它的数值到了10的9次方了,咋映射呢?总不可能再开这么大一个数组吧?会

    2024年02月11日
    浏览(47)
  • 25.选择排序,归并排序,基数排序

    目录 一. 选择排序 (1)简单选择排序 (2)堆排序 二. 归并排序 三. 基数排序 四. 各种排序方法的比较 (1)时间性能 (2)空间性能 (3)排序方法的稳定性能 (4)关于“排序方法的时间复杂度的下限” 一. 选择排序 (1)简单选择排序 基本思想:在待排序的数据中选出最

    2024年02月10日
    浏览(40)
  • 排序算法————基数排序(RadixSort)

    什么是基数排序???基数排序是一种和快排、归并、希尔等等不一样的排序...它不需要比较和移动就可以完成整型的排序。它是时间复杂度是O(K*N),空间复杂度是O(K+M ) 基数排序是一种借助多的思想对单逻辑进行排序的方法。 基数排序根据每个位来分配

    2024年02月13日
    浏览(35)
  • 【手撕排序算法】---基数排序

    个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【数据结构初阶(C实现)】 我们直到一般的排序都是通过的 比较和移动 这两种操作来进行排序的。 而今天介绍的基数排序并不是依靠的 比较和移动 来

    2024年02月16日
    浏览(35)
  • 排序算法——基数排序(C语言)

    什么是基数排序???基数排序是一种和快排、归并、希尔等等不一样的排序...它不需要比较和移动就可以完成整型的排序。它是时间复杂度是O(K*N),空间复杂度是O(K+M ) 基数排序是一种借助多的思想对单逻辑进行排序的方法。 基数排序根据每个位来分配

    2024年02月13日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包