Java实现基数排序(可支持负数)

1,212 阅读2分钟

最近在折腾排序算法,发现网上对基数排序大多数都是对正整数的总结,很少讲负数。查看资料,发现有两种方式可以简单的解决负数问题:

方式一:查找需要排序的数组最小值,如果最小值为负数,则数组中的所有元素减轻最小值,使得数组中不出现负数。(本文基于此方式实现)

方式二:将桶的大小从10扩大为20,负数从小到大在 0-9 号桶,正数从小到大在 10 - 19 号桶,具体代码实现可查看(juejin.cn/post/684490…)。

1、简介

基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部分资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序。

2、基本思想

将所有待比较数值统一为同样的数位长度,数位较短的的数前面补零。然后,从低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

3、图解

3.1 动态演示

3.2 有负数的情况下的图文说明

4、代码示例

public class RadixSort {

    public static void main(String[] args) {
        int[] arr = {-99, 53, -3, 542, 748, -48, 14, 214, -23, -56};
        radixSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void radixSort(int[] arr) {
        int maxValue = arr[0];
        int minValue = arr[0];
        for (int i = 1; i < arr.length; i++) {
            maxValue = Math.max(maxValue, arr[i]);
            minValue = Math.min(minValue, arr[i]);
        }
        // 如果最小值为负数,则数组中的数全部减去最小值,这样能保证数组中最小数是0
        if (minValue < 0) {
            for (int i = 0; i < arr.length; i++) {
                arr[i] -= minValue;
            }
            // 最大值也需要减,不然可能出现位数发生变化
            maxValue -= minValue;
        }

        int length = String.valueOf(maxValue).length();
        // 表示10个桶
        int[][] bucket = new int[10][arr.length];
        // 记录每个桶实际存放几个数据,比如:bucketElementCount[0]记录着bucket[0]桶放入数据个数
        int[] bucketElementCount = new int[10];

        for (int i = 0, j = 1; i < length; i++, j *= 10) {
            for (int k = 0; k < arr.length; k++) {
                int element = arr[k] / j % 10;
                bucket[element][bucketElementCount[element]] = arr[k];
                bucketElementCount[element]++;
            }

            int index = 0;
            // 遍历每个桶的数量,放入原数组
            for (int n = 0; n < bucketElementCount.length; n++) {
                if (bucketElementCount[n] != 0) {
                    for (int t = 0; t < bucketElementCount[n]; t++) {
                        arr[index++] = bucket[n][t];
                    }
                }
                // 需要把bucketElementCount置为0,不然会出错
                bucketElementCount[n] = 0;
            }
        }

        if (minValue < 0) {
            for (int i = 0; i < arr.length; i++) {
                arr[i] += minValue;
            }
        }
    }
}