基数排序(图文并茂,你一定看得懂)

基本思想:

将数组中的所有数按位进行分类,由于每一位数的大小都在0~9之间,因此创建下标为0~9的十个数组,根据需要对数进行存储

图文过程:

对于一组数字:8  9  6  11  23  1  9  18  10  213  33  7  87  91  180  35  52  716  106

选择个位数相同的元素,并成为一个数组

此时个位为i的数,分别别存储在下标为i的数组中
对数据开始进行收集,将数组重新整理,数组变为:
10  180  11  1  91  52  23  213  33  35  6  716  106  7  87  8  18  9  9

选择十位数为i的数的元素,并成为一个数组

此时十位为i的数,分别别存储在下标为i的数组中
对数据开始收集,将数组重新整理,数组变为:
1  6  106  7  8  9  9  10  11  213  716  18  23  33  35  52  180  87  91

选择百位数为i的数的元素,并成为一个数组

此时百位为i的数,分别别存储在下标为i的数组中
对数据开始收集,将数组重新整理,数组变为:
1 6 7 8 9 9 10 11 18 23 33 35 52 87 91 106 180 213 716 

这样整个数据就排序完成啦!

核心代码实现:

1.上面将数字填表的过程,实际上就是两个数组的叠加dyadic

List<ArrayList> dyadic = new ArrayList<ArrayList>();

该数组的横坐标,即为按照位数分配的下标,每个横坐标(下标)包含了一个数组,这个数组就是按照下标与自己的关系组成的

一共有0~9的取值,所以dyadic.add(new ArrayList())一共实现10次,即由这10个数组组成大数组dyadic

2.接下来是将原数组Array的元素分配给这是个小数组中,由于我们是按照最大数的位数决定循环次数的,因为需要找到整个数组Array的最大元素值,并决定循环次数,以上述数组为例,最大数是716,最高位为3,则循环三次

第一次寻找个位,第二次寻找十位,第三次寻找百位(其他更大数据以此类推)

寻找方法:以数字5432为例

 

通过上述图解,我们可以推出:位数值 x = num % (int)Math.pow(10, index + 1) / (int)Math.pow(10, index);   {注:pow方法是Math类中的,所以需要类名,且该方法是double类型的,所以需要强转成int类型的}

3.找到位数之后,就要将数组array中的元素按照位数和要求进行分类,原理即为图文原理中的图解,共进行times次

for(int j = 0; j < array.length; j++) {
     //找出每个数对应的位的数值
     int x = array[j] % (int)Math.pow(10, i + 1) / (int)Math.pow(10, i);
     //将该数组作为下标,找到对应的子数组
     ArrayList arr = dyadic.get(x);
     //将该元素添加到子数组中
     arr.add(array[j]);
     //因为子数组改变,因此更新大数组
     dyadic.set(x, arr);
}

4.将分配好的子数组中的值依次赋值给原数组array

//将重新排好的子数组的值依次将需要被排序的数组的值覆盖
            int index = 0;   //用index作为数组array的下标
            //将子数组依次遍历,将每个子数组中的元素添加到array中
            for(int k = 0; k < 10; k++) {
                //当下标为k的子数组中有元素时
                while(dyadic.get(k).size() > 0) {
                    //得到该数组
                    ArrayList arr = dyadic.get(k);
                    ///将该数组的第一个元素添加到array中
                    array[index] = (int)arr.get(0);
                    //移除子数组中的第一个元素,这样就能在第一个元素被使用之后,后面元素替换
                    arr.remove(0);
                    //将array数组中下标也后移一位
                    index++;
                }
            }

这样,整个原理过程就完成啦

不过要注意,上述过程只适合正整数的排序,如果是负数的话,就会出现下标越界的异常,但不用担心,因为这种方法同样适用于负整数,只不过需要一些小改动,即要对元素的正负进行判断,如果是负数,则需要绝对值化,并将结果反转即可

完整代码(不含负数)

package sort;

import java.util.ArrayList;
import java.util.List;

public class BasicSort {
    public static void basicSort(int[] array) {
        //创建叠加数组
        List<ArrayList> dyadic = new ArrayList<>();
        //给大数组dyadic添加子数组
        for(int i = 0; i < 10; i++) {
            ArrayList<Integer> arr = new ArrayList<>();
            dyadic.add(arr);
        }

        //找出数组中的最大值
        int max = 0;
        for(int i = 0; i <array.length; i++) {
            if(array[i] > max) {
                max = array[i];
            }
        }

        //判断最大值为几位数,其位数就是应该循环的次数
        int times = 0;
        while(max > 0) {
            max /= 10;
            times++;
        }

        //循环times次,每次将对应位的数分配到相应的自数组中
        for(int i = 0; i < times; i++) {
            for(int j = 0; j < array.length; j++) {
                //找出每个数对应的位的数值
                int x = array[j] % (int)Math.pow(10, i + 1) / (int)Math.pow(10, i);
                //将该数组作为下标,找到对应的子数组
                ArrayList arr = dyadic.get(x);
                //将该元素添加到子数组中
                arr.add(array[j]);
                //因为子数组改变,因此更新大数组
                dyadic.set(x, arr);
            }

            //将重新排好的子数组的值依次将需要被排序的数组的值覆盖
            int index = 0;   //用index作为数组array的下标
            //将子数组依次遍历,将每个子数组中的元素添加到array中
            for(int k = 0; k < 10; k++) {
                //当下标为k的子数组中有元素时
                while(dyadic.get(k).size() > 0) {
                    //得到该数组
                    ArrayList arr = dyadic.get(k);
                    ///将该数组的第一个元素添加到array中
                    array[index] = (int)arr.get(0);
                    //移除子数组中的第一个元素,这样就能在第一个元素被使用之后,后面元素替换
                    arr.remove(0);
                    //将array数组中下标也后移一位
                    index++;
                }
            }
        }
    }
}

测试代码

package sort;

import static sort.BasicSort.basicSort;

public class Test {
    public static void main(String[] args) {
        int[] array = new int[]{2, 9, 1, 32, 31, 6, 22, 0};
        basicSort(array);
        for(int i : array) {
            System.out.println(i);
        }
    }
}

 

 

 

 

  • 29
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值