基数排序 以及基数排序优化版

package com.company.排序;

import java.util.Arrays;

public class 基数排序 {
    public static void main(String[] args) {
        int a[]=new int[]{1,3,6,9,14,0,89,4,5};
        radixSort(a);
        System.out.println(Arrays.toString(a));
    }
    public static void radixSort(int[] arr) {

        int max=arr[0];//假设第一个数就是最大数
        for(int i=1;i<arr.length;i++) {
            if(arr[i]>max) {
                max=arr[i];
            }
        }
        int maxLength=(max+" ").length();
        //第一轮(针对每个元素的个位进行排序处理)

        //定义一个二维数组,表示10个桶,每个桶就是一维数组
        //说明:
        //1.二维数组包含10个一维数组
        //2.为了防止在放入数的时候,数据溢出,则每个一个数组(桶),大小定为arr.length
        //3明显,基数排序是使用空间换时间
        int[][] bucket=new int[10][arr.length];

//		为了记录每个桶中,实际存放了多少个数据,我们定义了一个一维数组来记录各个桶中的个数
        int[] bucketElementCounts=new int[10];

        for(int i=0,n=1;i<maxLength;i++,n*=10) {
            for(int j=0;j<arr.length;j++) {
                //取出每个元素的对应位的值进行排序处理,第一次是个位,第二次是十位。。。
                int digitOfElement=arr[j]/n%10;
                //放入到对应的桶中
                bucket[digitOfElement][bucketElementCounts[digitOfElement]]=arr[j];
                bucketElementCounts[digitOfElement]++;
            }

            //按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
            int index=0;
            //遍历每一桶,并将桶中的数据,放入到原数组
            for(int k=0;k<bucketElementCounts.length;k++) {
                //如果桶中,有数据,我们才能放入到原数组
                if(bucketElementCounts[k]!=0) {
                    //循环该桶即第k个桶,(即第k个一维数组),放入
                    for(int l=0;l<bucketElementCounts[k];l++) {
                        //取出元素放入arr
                        arr[index]=bucket[k][l];
                        index++;
                    }
                }
                //第i+1轮处理后,需要将每个bucketElementCounts[k]=0!!!
                bucketElementCounts[k]=0;
            }
        }
    }

}

优化版 从二维数组简化到一维数组

public class 基数排序test {
    public static void main(String[] args) {
        int a[]=new int[]{1,3,6,9,14,0,89,4,5};
        radixSort(a);
        System.out.println(Arrays.toString(a));
    }
    public static void radixSort(int[] arr) {

        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 = 1; i <= maxLength; i++) {
            int[] count = new int[10];//定义一个一维数组,表示i位上小于等于下标的数有几个,

            int[] bucket = new int[arr.length];//辅助数组 暂存数据

            //表示i位上等于下标的数有几个
            for (int index = 0; index < arr.length; index++) {
                int digit = getDigit(arr[index], i);
                count[digit]++;
            }
            //表示i位上小于等于下标的数有几个,
            for(int index=1; index<10; index++){
                count[index] += count[index-1];
            }
            //从后向前遍历  经过此次排序 排第几
            for(int index = arr.length-1; index>=0; index--){
                int digit = getDigit(arr[index], i);
                count[digit]--;
                bucket[count[digit]]=arr[index];
            }
            //重新写回原数组
            for(int index = 0; index <arr.length; index++){
                arr[index] = bucket[index];
            }
        }
    }
    private static int getDigit(int x, int index){//获取第 index 位上的数
        for(int i=1; i<index; i++){
            x=x/10;
        }
        return x%10;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值