基数排序详解

1、什么是基数排序

        基数排序是桶排序的扩展,也是一种非比较排序。桶排序适用于数据分布比较均匀的情况,如果数据分布不是很均匀,并且数据中存在几个极大值,这会导致桶排序存在很多的空桶,这会造成内存的浪费,桶排序使用的是序列中元素的范围,基数排序使用的是序列中元素的位数,基数排序由于位数的范围是10位或者26位,所以可以避免创建过多的桶。基数排序将数据划分为一个个的关键字,其对相同数位上的关键字进行计数排序,如果位数不够则前面补0,从低位到高位进行排序,如果字符串比较可以从左到右比较。


2、基数排序的应用场景

 基数排序适用于大范围的整数排序和字符串排序。


3、基数排序的思想

        基数排序整体来看是一种“分配和收集”排序,其将序列中的元素按照位数进行划分,不够的补0,将相同位数的元素先分配,分配后相同位数的元素排好序后,进行收集,重复该操作,可以完成排序。也可以这样理解,基数排序使用的是一种分治思想,对序列中相同位数的元素进行计数排序,所有的位数循环完成,则排序完成。


4、基数排序的步骤


基数排序的步骤:
        1、获取序列中的最大值,获取其长度length
        2、新建一个二维数组用于模拟桶存放数据,取临时变量temp=1
        3、循环的次数为length,新建数组count,用于保存各个桶中元素的个数,遍历原序列,序列中的元素先除以temp,再对10取余则可以得到,元素中个位数的值,将其放入各自编号的桶中,遍历结束,遍历count将排完序的数据放入到原数组中正确的位置,以此类推获取百位数,千位数,直到length循环结束。


5、基数排序的Java代码

public class RadixSorte {

    /**
     * 基数排序
     *
     * @param args
     */
    public static void main(String[] args) {
        int[] arr = {11, 12, 3, 43, 87, 11, 9, 0, 76, 35,
                21, 22, 33, 11, 22, 345, 543, 321, 123,
                456, 987, 789, 876, 12, 23, 3, 1, 9, 999};
        radixSort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }

    private static void radixSort(int[] arr) {
        if (arr == null || arr.length == 0) {
            return;
        }
        // 获取最大值
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        // 用二维数组模拟桶放入东西,一共有10个桶
        int[][] temp = new int[10][arr.length];

        // 元素最大值的长度
        String maxString = max + "";
        int length = maxString.length();
        int temp1 = 1;
        for (int i = 0; i < length; i++) {
            // 用于记录每个桶中放入元素的位置
            int[] count = new int[10];
            for (int i1 = 0; i1 < arr.length; i1++) {
                int i2 = (arr[i1] / temp1) % 10;
                temp[i2][count[i2]] = arr[i1];
                count[i2]++;
            }
            temp1 *= 10;

            // 将数据取出放入原数组
            int sum = 0;
            for (int i1 = 0; i1 < count.length; i1++) {
                for (int i2 = 0; i2 < count[i1]; i2++) {
                    arr[sum++] = temp[i1][i2];
                }
            }
        }
    }


}

6、基数排序的总结


         基数排序的时间复杂度是O(k(n+d)),空间复杂度为O(dn),是稳定性算法。(k是位数,n是序列的长度,d是桶的个数)
        基数排序的时间复杂度是O(k(n+d)):根据上面的代码可以推出时间复杂度为n+k(n+d),所以时间复杂度为O(k(n+d))
        空间复杂度为O(dn):创建一个二维数组和一个记录个数,所以空间复杂度为O(dn)
        是稳定性算法:相同的元素在同一个桶里面,按照原来的顺序排列,所以是稳定性算法。

7、基数排序的类比


        基数排序主要是“分配和收集”,类似于:老师想将学生的成绩从小到大排序,则每月考一次试,难度越来越大,每次考完都进行一次排名。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值