排序系列 之 基数排序

  • !!!排序仅针对于数组哦
  • 本次排序是按照升序来的哦

介绍

  • 基数排序(RadixSort)又称桶子法,是一种非比较型整数排序算法。其原理是将整数按位数切割成不同的数组,然后按每个位数分别比较,通过简直的各个位的值,将要排序的元素分配至某些“桶”中。
    (是不是看着有点懵,不急,咱看基本思路,可以结合过程图看哦😊)

思路图

  • 先来个数组:int[] arr = {1260,134,209,408,34,68907,29,1034,51,855,2,33,566,7,12};

  • 带有阴影色的算是个小进阶,第一遍看时忽略掉阴影数值,第二次可以带上阴影数值一起看~

    本人呢开始对最大位数后边排序有点怀疑,然后就添加了个有阴影色的数值,用来判断对于相同位数的值,最后一次会不会排好序,算是个小进阶吧

在这里插入图片描述

整理整理思路

  • 需要定义一个二维数组,包含是个桶,每个桶的长度为数组的长度(最坏情况下,所有的数值都到一个桶里了):
    int[][] bucket = new int[10][arr.length];
    
  • 需要再来一个数组,用来记录每个桶内的数据长度,即往桶内放入数据时应放入的位置
    int[] elementCount = new int[10];
    
  • 找到数组中的最大值,并确认最高位,也就是需要遍历的次数
    int MAX_NUM;
    int lenNum = (MAX_NUM+"").length();
    
  • 定义一个除数因子,初始化为1
    int factor = 1;
    
  • 然后就是开始遍历,放入数据,取出数据,然后除数因子*10
  • 思路捋顺,开始走代码吧~

代码

public class RadixSort {
    public static void main(String[] args) {
        int[] arr = {1260,134,209,408,34,68907,29,1034,51,855,2,33,566,7,12};
        int[] arr2 = {1260,68909,134,209,72311,408,34,68907,29,1034,51,855,2,33,566,7,12};
        sort(arr);
        sort(arr2);
        System.out.println("arr:"+Arrays.toString(arr));
        System.out.println("arr2:"+Arrays.toString(arr2));
    }

    public static void sort(int[] arr){
        // 定义桶,用来存放个位、十位、百位...等取余的数值
        int[][] bucket = new int[10][arr.length]; // 10个桶,每个桶的长度不确定,最差情况是都去一个桶了
        // 定义桶记录,用来记录桶内数据长度
        int[] elementCount = new int[10];  // 一维数组长度是10,每个数代表每个桶的有效数据长度

        // 找到数组中的最大值,用来确定取余需要几次
        int MAX_NUM = arr[0];  // 假设第一个是最大值
        for(int i=1;i<arr.length;i++){
            if(arr[i]>MAX_NUM){
                MAX_NUM = arr[i];
            }
        }
        // 计算最大数的长度
        int lenNum = (MAX_NUM+"").length();
        // 定义一个除数因数
        int factor = 1;

        // 开始操作数据,首先确定要计算几次
        for(int m=0;m<lenNum;m++){
            // 数据放入
            for(int i=0;i<arr.length;i++){
                int element = arr[i]/factor%10;  // 取余后的数值,即要放到的桶的位置
                int count = elementCount[element]; // 先找到要放入的桶的位置
                bucket[element][count] = arr[i];
                elementCount[element]++;  // 桶的位置需要增加,但是每次进来count是刚刚获取到的,所以不能使用count++
            }

            // 数据取出
            // 首先定义一个变量用来指向原数组的下标,因为数据取出来需要写回原数组
            int index = 0;
            for(int i=0;i<10;i++){
                if(elementCount[i]!=0){ // 判断桶的长度,只有不是空的时候才会读取数据
                    // 开始读取数据
                    for(int j=0;j<elementCount[i];j++){ // 第i个桶,从0开始读取
                        arr[index] = bucket[i][j];  // 第i个桶,第j个位置,依次写入数据中,下标就是index
                        index++;
                    }
                }
                // 读取完毕后需要将记录变更为0,因为下一轮的时候是从0开始存储的
                elementCount[i] = 0;
            }

            // 变更取余的对象
            factor = factor*10;
        }
    }
}
-------------------------运行结果----------------------------
arr:[2, 7, 12, 29, 33, 34, 51, 134, 209, 408, 566, 855, 1034, 1260, 68907]
arr2:[2, 7, 12, 29, 33, 34, 51, 134, 209, 408, 566, 855, 1034, 1260, 68907, 68909, 72311]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值