基数排序学习

根据桶子法思想自己写的,目前运行正常,有没有不足还不知道

package com.www.demo06;

public class BasicData {
    public static void main(String[] args) {
//        int[] arr = new int[]{53,542,3,63,14,214,154,748,616,589};
        int[] arr = new int[]{3,542,63,53};
        sort(arr);
    }

    public static void sort(int[] arr){
        //数据个数
        int num = arr.length;

        //查出这些数据最大数的位数
        int max = 0;//代表最大值
        for (int i = 0;i < num;i++){
            if (arr[i] > max){
                max = arr[i];
            }
        }
        int units = (max + "").length();//位数

        //桶子法
        int[][] arr1 = new int[10][num];//十个桶

        //操作桶里的数字:数组数据按照权重从低到高顺序放入桶中(放-取-放-取)
        for(int k = 0; k < units;k++){//取得每一位数的方法:除以该位权重之后取模10(从低到高)
            //放
            for (int i = 0;i < num;i++){//对每一个数据进行处理,i代表每一位数据位置
//                int temp = arr[i] / (10^k) % 10;//取出数组中数据,得到权重对应数字----试了一下,java中^作用和减法一样
                int temp = arr[i] / (int)Math.pow(10, k) % 10;
                for(int j = 0;j <num;j++){
                    if (arr1[temp][j] == 0){
                        arr1[temp][j] = arr[i];//按照个位数与数组下标对应的方式放置到桶里,j代表每个桶中的各个位置
                        break;
                    }
                }
            }
            //取----按照个位数从小到大取出:先取一维再,同一维里的二维
            int point = 0;//一维数组下标
            for(int i = 0;i < 10;i++){//每个桶
                    for (int j = 0; j < num; j++) {//桶里的数据
                        if (arr1[i][j] != 0) {
                            arr[point] = arr1[i][j];//只要值不为0,那一定放数据了,不用担心point超,本来桶里放的就是arr中的数据
                            arr1[i][j] = 0;
                            point++;
                        }else{
                            break;
                        }
                    }
                    if (point == num){
                        break;
                    }
            }
        }
        //将排序好的数字打印出来
        for (int i = 0;i < num;i++){
            System.out.println(arr[i]);
        }
    }
}

时间复杂度:k/2*num^2(k代表位数)?
参考网上资料,对代码做了一些修改,增加一个辅助数组,用来指示每个桶中的数据个数,放数据时,不用依次判断了

package com.www.demo06;

public class BasicData1 {
    public static void main(String[] args) {
        int[] arr = new int[10];
        for (int i = 0; i < 10;i++){
            arr[i] = (int)(Math.random()*1000);
        }
        show(arr);
        sort(arr);
        show(arr);
    }

    public static void show(int[] arr){
        for (int i = 0;i < arr.length;i++){
            System.out.println(arr[i]);
        }
    }

    public static void sort(int[] arr){
        int num = arr.length;//数据个数

        //查出这些数据最大数的位数:便于取出每一位数据
        int max = 0;
        for (int i = 0;i < num;i++){
            if (arr[i] > max){
                max = arr[i];
            }
        }//最大值,时间复杂度(num)
        int units = (max + "").length();//位数
        int power = (int)Math.pow(10,units);

        //桶子法
        int[][] arr1 = new int[10][num];//十个桶
        int[] arr2 = new int[10];//辅助数组:记录每个桶中有多少数据

        //操作桶里的数字:数组数据按照权重从低到高顺序放入桶中(放-取-放-取)
        for(int k = 1; k < power;){//取得每一位数的方法:除以该位权重之后取模10(从低到高)
            //放
            for (int i = 0;i < num;i++){
                int temp = arr[i] / k % 10;//每个数据对应temp桶
                arr1[temp][arr2[temp]] = arr[i];
                arr2[temp]++;//对于temp标号的桶,每放入一个数据,下标就向后移一位
            }//时间复杂度:num
            //取
            int point = 0;//一维数组下标
            for(int i = 0;i < 10;i++){//每个桶
                for (int j = 0; j < arr2[i]; j++) {//桶里的数据
                    arr[point] = arr1[i][j];
                    point++;
                }
                arr2[i] = 0;
            }//时间复杂度:num + 10
            k *= 10;
        }//units(2*num+10)
    }
}

看了一下别人的时间复杂度,好像比我的少
网上看了一个别人写的,桶没有设立二维数组,而是有多少数据,建立多大的一维数组

辅助数组**a[i]的值减去a[i-1]**的值表示位数为i的数据的个数

a[i]-1的值就对应了放位数值i的桶的最大下标
这是个大致思路,具体实现这里就不放了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新手学java2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值