排序算法之基数排序

基数排序是一种非比较排序算法,通过分配和收集策略,按位数进行排序。它适合于大范围整数和字符串排序,具有线性时间复杂度O(k(n+d))和稳定性的特点。文章详细介绍了基数排序的思想、步骤,并提供了Java代码实现示例。
摘要由CSDN通过智能技术生成

目录

1、什么是基数排序?

2、基数排序的应用场景

3、基数排序的思想

4、基数排序的步骤

5、代码实现

6、基数排序的总结

7、基数排序的类比


1、什么是基数排序?

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

2、基数排序的应用场景

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

3、基数排序的思想

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

4、基数排序的步骤

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

5、代码实现

package com.kgf.algorithm.sort;

/***
 * 基数排序
 */
public class RadixSorte {

    public static void main(String[] args) {
        int[] nums = {1, 4, 9, 2, 5, 3, 7, 6, 22, 23, 15, 24, 0, 3,
                4, 5, 2, 3, 5, 12, 1, 3, 4, 2, 1,
                3, 45, 1, 1};
        RadixSorte rs = new RadixSorte();
        rs.radixSort(nums);
        for (int num : nums) {
            System.out.print(num+"\t");
        }
        System.out.println();
    }

    /***
     * @param nums
     */
    public void radixSort(int[] nums){
        //首先获取序列中的最大和最小值
        int max = nums[0];
        for (int i = 0; i < nums.length; i++) {
            if (max<nums[i]){
                max = nums[i];
            }
        }
        String maxStr = max+"";
        //创建二维数组
        int[][] temp = new int[10][nums.length];
        int temp1 = 1;
        for (int i = 0; i < maxStr.length(); i++) {
            //计算到哪个桶中
            int[] countArr = new int[10];
            for (int j = 0; j < nums.length; j++) {
                int targetRadix = (nums[j]/temp1) % 10;
                temp[targetRadix][countArr[targetRadix]] = nums[j];
                countArr[targetRadix]++;
            }
            temp1 = temp1*10;
            //开始调整数组中元素的位置
            int sum = 0;
            for (int j = 0; j < countArr.length; j++) {
                for (int k = 0; k < countArr[j]; k++) {
                    nums[sum++] = temp[j][k];
                }
            }
        }
    }
}

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、基数排序的类比

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值