【Java】十大排序算法之基数排序

基数排序

第一步:将数组中的最大值找出来并记录
第二步:确定最大值是几位数并记录
第三步:利用位数从右到左放入桶里(即个、十、百、千~)
第四步:将桶里的值依次拿出覆盖到原先数组里面

例如:3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48
看个位数:(代码里面取模后算出怕是单位负数最小值负9,所以统一全部加10)

34438547153626272464195048
131418151715161617121614191018

放入对应桶里:

101213141516171819
502344,45,1536,26,4647,2738,4819

然后依次取出:
50, 2, 3, 44, 4, 5, 15, 36, 26, 46, 47, 27, 38, 48, 19

看十位数:(代码里面取模后算出怕是单位负数最小值负9,所以统一全部加10)

50234445153626464727384819
151010141010101312141412131411

放入对应桶里:

101112131415
2,3,4,515,1926,2736,3844,46,47,4850

然后依次取出:
2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50

public class RadixSortTest {

    public static void main(String[] args) {
        int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
        int maxDigit = getMaxDigit(arr);
        int[] sort = radixSort(arr, maxDigit);
        System.out.println(Arrays.toString(sort));
    }

    // 获取最大值的位数
    public static int getMaxDigit(int[] arr) {
        int maxValue = getMaxValue(arr);
        return getNumLength(maxValue);
    }

    // 获取数组里的最大值
    public static int getMaxValue(int[] arr) {
        int maxValue = arr[0];
        for (int value : arr) {
            if (maxValue < value) {
                maxValue = value;
            }
        }
        return maxValue;
    }

    // 求位数,例如 10 是两位,100 是三位
    public static int getNumLength(long num) {
        if (num == 0) {
            return 1;
        }
        int length = 0;
        for (long temp = num; temp != 0; temp /= 10) {
            length++;
        }
        return length;
    }

    public static int[] radixSort(int[] arr, int maxDigit) {
        int mod = 10;
        int dev = 1;

        for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {

            // int[][] counter = new int[mod * 2][0];
            // 考虑负数的情况,这里扩展一倍队列数,其中 [0-9]对应负数,[10-19]对应正数 (bucket + 10)
            // 创建了20个桶(行数),每个桶暂时没有元素
            int[][] counter = new int[20][0];

            for (int j = 0; j < arr.length; j++) {

                // int bucket = ((arr[j] % mod) / dev) + mod;
                // mod 换为 10 保证了如果是负数位数为 9,bucket 能保证大于 0
                int bucket = ((arr[j] % mod) / dev) + 10;
                // 外循环第一次 mod = 10, dev = 1:
                // 3   44  38  5   47  15  36  26  27  2   46  4   19  50  48
                // 13  14  18  15  17  15  16  16  17  12  16  14  19  10  18
                // 外循环第二次 mod = 100, dev = 10:
                // 50  2   3   44  4   5   15  36  26  46  47  27  38  48  19
                // 15  10  10  14  10  10  11  13  12  14  14  12  13  14  11


                // 每次循环数据对应桶进行插入(桶原先是没有元素,先扩容后插入)
                counter[bucket] = arrayAppend(counter[bucket], arr[j]);
                // 外循环第一次后桶:
                // 10:50
                // 12:2
                // 13:3
                // 14:44 4
                // 15:5  15
                // 16:36 26 46
                // 17:47 27
                // 18:38 48
                // 19:19
                // 外循环第二次后桶:
                // 10:2  3  4  5
                // 11:15 19
                // 12:26 27
                // 13:36 38
                // 14:44 46 47 48
                // 15:50
            }

            int pos = 0;
            // 第一次外循环后数组变成:50  2   3   44  4   5   15  36  26  46  47  27  38  48  19
            // 第二次外循环后数组变成:2   3   4   5   15  19  26  27  36  38  44  46  47  48  50
            for (int[] bucket : counter) {
                for (int value : bucket) {
                    arr[pos++] = value;
                }
            }
        }

        return arr;
    }

    // 自动扩容,并保存数据
    public static int[] arrayAppend(int[] arr, int value) {
        arr = Arrays.copyOf(arr, arr.length + 1);
        arr[arr.length - 1] = value;
        return arr;
    }
}

参考:基数排序动图演示及代码

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值