algorithm:基数排序

import java.util.Arrays;

public class RadixSort {
    public static void main(String[] args) {
        int[] arr = {4, 34, 19, 1, 9, -1};
        System.out.println("排序前为:" + Arrays.toString(arr));
        radixSort(arr);
        System.out.println("排序后为:" + Arrays.toString(arr));
    }

    /**
     * i为数组中元素的位数;j为数组中的每一个元素;k为每一个桶;l为桶中存放的每一个元素
     * 负数处理思路:先判断有无负数,有则找到最小值,如果有负数,数组所有元素减去负数最小值,使得数组最小值变为0
     * 接下来按正整数排序,最后数组所有数据加上原最小数,变为原有数据值
     */
    public static void radixSort(int[] arr) {
        // 假设数组中最大的数是第一位的数
        int max = arr[0];
        int min = 0;
        // 找出数组中最大的正数或最小的负数
        for (int i = 1; i < arr.length; i++) {
            // 找最大的正数
            if (arr[i] > max) {
                max = arr[i];
            }
            // 找最小的负数
            if (arr[i] < min) {
                min = arr[i];
            }
        }
        // 如果有负数,数组所有元素减去负数最小值,使得数组最小值变为0
        if (min < 0) {
            for (int i = 0; i < arr.length; i++) {
                arr[i] -= min;
                max -= min;
            }
        }
        // 最大数的位数
        int maxDigit = (max + "").length();

        // 定义一个二维数组,前9个桶存放-1~-9,后10个桶存放0~9
        // 其中每个桶极限情况下可以存放数组中的所有元素,防止溢出
        int[][] bucket = new int[10][arr.length];
        // 定义一个数组,表示这19个桶中实际存放元素的个数,其中bucketIn[0]表示第0个桶中实际存放元素的个数
        int[] counts = new int[10];

        // 对元素的位数进行排序处理
        for (int i = 0, n = 1; i < maxDigit; i++, n *= 10) {
            // 对数组中的元素进行处理
            for (int j : arr) {
                // 计算数组中取出元素的位数
                int digit = j / n % 10;
                // 将元素放入对应位数的桶中,元素放入桶中的位置为桶中已有的元素个数
                // 之后将下标加1,处理下一个位置
                bucket[digit][counts[digit]++] = j;
            }

            // 原来数组的下标
            int index = 0;
            // 遍历每一个桶,bucket数组的顺序与counts数组的顺序一致
            for (int k = 0; k < counts.length; k++) {
                // 如果桶中有元素
                if (counts[k] != 0) {
                    // 依次取出并放入到原来数组
                    for (int l = 0; l < counts[k]; l++) {
                        arr[index++] = bucket[k][l];
                    }
                    // 将第k个桶中的元素取出之后,需要清零,用以下一次存放元素
                    counts[k] = 0;
                }
            }
        }
        // 如果数组中有负数,还原这些负数
        if (min < 0) {
            for (int i = 0; i < arr.length; i++) {
                arr[i] += min;
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值