稳定的基数排序

1. 思路

蛮复杂的,可以准备十个桶分别放 当前位为 0-9 的数,也可以只用一个数组,预留好对应的位置,本题就是这样。
从低位往高位循环,每次把数放到对应的位置,再拿出来。

2. 过程

  1. 准备好辅助数组help,用来存 当前位为 0-9 的数
  2. 获取本数组中最大数值的位数,并以此来循环,表示每次 当前位 的元素取出,放入对应桶(位置)
    2.1. 根据 当前位 元素,放入对应桶(数组对应位置)count数组是专门用来存预留多少位的
    2.2. 依次计算count[]数组,值为之前的值+当前值,用以表示需要预留多少位
    2.3. 从右往左遍历原数组 arr,放到help数组中
    2.4. 把help数组中的本次放入取出的结果 赋值回 原数组

3. 代码

package mca.class08;

/**
 * @ClassName RadixSort
 * @Descriotion TODO
 * @Author nitaotao
 * @Date 2022/10/3 9:31
 * @Version 1.0
 **/
public class RadixSort {

    /**
     * 返回当前序列最大是几位数
     *
     * @param arr
     * @return
     */
    public static int maxbits(int[] arr) {
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < arr.length; i++) {
            max = Math.max(max, arr[i]);
        }
        int res = 0;
        while (max != 0) {
            res++;
            max /= 10;
        }
        return res;
    }

    /**
     * arr[L...R]排序,最大值的十进制位数 digit
     *
     * @param arr
     * @param L
     * @param R
     * @param digit digit位的十进制数
     */
    public static void radixSort(int[] arr, int L, int R, int digit) {
        final int radix = 10;
        //arr中的数的下标
        int i = 0;
        //当前数多少位
        int j = 0;

        //预留的位置
        //有多少个数就准备多少个空间
        //默认全是>=0,当然,如果有负数也好办,
        //找到最小负数,所有数 + 最小负数的绝对值,让最小值归零,排完序再减去对应值
        int[] help = new int[R - L + 1];
        for (int d = 1; d <= digit; d++) {
            //有多少位就进出多少次
            //10个空间
            //count[0] 当前位(d位)  是0的数有多少个
            //count[1] 当前位(d位)  是[0,1]的数有多少个
            //count[2] 当前位(d位)  是[0,2]的数有多少个
            //count[i] 当前位(d位)  是[0,i]的数有多少个

            // count[0,9]
            //每个数个位是几,那个位置就数量+1
            int[] count = new int[radix];
            for (i = L; i <= R; i++) {
                j = getDigit(arr[i], d);
                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], d);
                //代替十个桶
                //预留count[j]个位置
                //从右往左模拟倒出元素
                help[count[j] - 1] = arr[i];
                count[j]--;
            }
            //复制回原数组
            for (i = L, j = 0; i <= R; i++, j++) {
                arr[i] = help[j];
            }

        }


    }

    //取最后一位数

    /**
     * 取x数倒数第d位
     *
     * @param x
     * @param d
     * @return
     */
    public static int getDigit(int x, int d) {
        //挪移多少位
        System.out.println(d);
        int a = (int)(Math.pow(10, d - 1));
        System.out.println(a);
        //取到多少位
        int b = x / a;
        return b % 10;
    }

    public static void radixSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        radixSort(arr, 0, arr.length - 1, maxbits(arr));
    }
    public static void main(String[] args) {
        int[] arr = {1, 9, 3, 5, 25, 354, 3155, 44, 3, 7};
        radixSort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

4. 时间复杂度O(N+K)

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值