算法——基数排序

Posted 高、远

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法——基数排序相关的知识,希望对你有一定的参考价值。

基数排序就是利用空间换时间,他需要一个10*arr.length的空间,所以当需要排序的数组非常大的时候,特别浪费空间,很可能OOM,基数排序是一个稳定的,时间复杂度较低的排序算法

桶排序的升级版本:

/** 基数排序
     * 桶排序升级版
     *
     * @param arr
     */
    public static void radix(int[] arr) {
        //定义10个桶,每个桶的大小都能装满整个数组
        int[][] bucket = new int[10][arr.length];

        //每一次取数的时候arr的下表
        int index = 0;

        //base表示个位数值或者十位、百位、千位等
        int base = 0;

        //定义一个一位数组记录每个桶中有多少个数据,方便取出
        //因为每一轮存数据的时候是覆盖式的存,并没有真正的从桶中删除上一轮的数据
        //所以不能用bucket[k].length来确定个数
        int[] bucketCounts = new int[10];

        //找出最大的数,循环的次数与最大的数有关
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max)
                max = arr[i];
        }

        //算出最大的数有几位,这里运用字符串的函数,比较巧妙
        int maxLength = (max + "").length();

        //将数组中的数全部放入到桶中
        for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
            //每次循环都按照每一位的大小放入到相应的桶中
            for (int j = 0; j < arr.length; j++) {
                //取出该位对应的值
                base = arr[j] / n % 10;
                bucket[base][bucketCounts[base]] = arr[j];
                bucketCounts[base]++;
            }

            //取出数据放到arr数组中,循环桶的个数,每一轮把一个桶中的数全部放入数组中
            index = 0;
            for (int k = 0; k < bucket.length; k++) {
                if (bucketCounts[k] != 0) {
                    for (int j = 0; j < bucketCounts[k]; j++) {
                        arr[index++] = bucket[k][j];
                    }
                }
                //每次循环把数放到桶中之后就将bucketCounts重置!!!特别重要!!!!
                //否则下次取数就会出错
                bucketCounts[k] = 0;
            }
        }
    }

全部代码:

package algorithm.sort.radixSort;

import java.util.Arrays;

public class Radix {
    public static void main(String[] args) {
        int[] arr = {19, 97, 9, 17, 1, 8, 27};
        radix(arr);
        System.out.println(Arrays.toString(arr));

    }

    /** 基数排序
     * 桶排序升级版
     *
     * @param arr
     */
    public static void radix(int[] arr) {
        //定义10个桶,每个桶的大小都能装满整个数组
        int[][] bucket = new int[10][arr.length];

        //每一次取数的时候arr的下表
        int index = 0;

        //base表示个位数值或者十位、百位、千位等
        int base = 0;

        //定义一个一位数组记录每个桶中有多少个数据,方便取出
        //因为每一轮存数据的时候是覆盖式的存,并没有真正的从桶中删除上一轮的数据
        //所以不能用bucket[k].length来确定个数
        int[] bucketCounts = new int[10];

        //找出最大的数,循环的次数与最大的数有关
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max)
                max = arr[i];
        }

        //算出最大的数有几位,这里运用字符串的函数,比较巧妙
        int maxLength = (max + "").length();

        //将数组中的数全部放入到桶中
        for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
            //每次循环都按照每一位的大小放入到相应的桶中
            for (int j = 0; j < arr.length; j++) {
                //取出该位对应的值
                base = arr[j] / n % 10;
                bucket[base][bucketCounts[base]] = arr[j];
                bucketCounts[base]++;
            }

            //取出数据放到arr数组中,循环桶的个数,每一轮把一个桶中的数全部放入数组中
            index = 0;
            for (int k = 0; k < bucket.length; k++) {
                if (bucketCounts[k] != 0) {
                    for (int j = 0; j < bucketCounts[k]; j++) {
                        arr[index++] = bucket[k][j];
                    }
                }
                //每次循环把数放到桶中之后就将bucketCounts重置!!!特别重要!!!!
                //否则下次取数就会出错
                bucketCounts[k] = 0;
            }
        }
    }
}

以上是关于算法——基数排序的主要内容,如果未能解决你的问题,请参考以下文章

数据结构-排序之基数排序(使用java代码实现)

数据结构-排序之基数排序(使用java代码实现)

数据结构-排序之基数排序(使用java代码实现)

经典十大排序算法(含升序降序,基数排序含负数排序)Java版完整代码建议收藏系列

c中的基数排序算法[关闭]

数据结构之排序算法Java实现—— 基数排序法