排序——基数排序

一、基本介绍

​ 基数排序属于稳定的排序,排序时将待比较数统一数位长度,数位较短的数前面补零;然后从最低位开始,依次进行一次排序,这样从最低位一直到最高位排序完成之后,待排序数组便完成排序。

二、排序过程

对数组arr = [3 , 52 , 67 , 57 , 720 ] 从小到大排序过程如下:

  1. 第一趟排序

    • 首先初始化十个桶用于排序,将待排序数组根据个位数值依次放入对应的桶中;

    • 图例如下

![](https://img2018.cnblogs.com/blog/1226846/202002/1226846-20200219191416362-940767417.png)


  - 然后将数据从桶中依次取出,放到数组中,得到新数组 arr = [720 , 52 , 3 , 67 , 57]。

2. 第二趟排序

   - 将第一轮的新数组根据十位数数值大小依次放入到对应的桶;
   - 图例如下

![](https://img2018.cnblogs.com/blog/1226846/202002/1226846-20200219191439705-1209881088.png)


   - 然后将数据从桶中依次取出,放到数组中,得到新数组 arr = [3 , 720 , 52 , 57 , 67]。

3. 第三趟排序

   - 将第二趟排序的新数组根据百位数数数值大小依次放入到对应的桶;
   - 图例如下

![](https://img2018.cnblogs.com/blog/1226846/202002/1226846-20200219191457309-1200694267.png)

   - 将数据依次从桶中取出便可完成排序,最终结果为 arr = [2 , 52 , 57 , 67 , 720]。

三、代码实现

​ 通过以上分析,可以发现基数排序的趟数取决于待排序数组中的最大的数据位数。可以定义一个二维数组来表示桶,桶的大小为防止数组越界,所以大小设置为待排序数组的长度。此外还需要设置一个数组来保存每个桶中一存入数据的个数,以便于后续从桶中取出数据。

public static void radixSort(int[] arr) {
    if (arr == null || arr.length < 2) {//数组为空或者长度为1直接返回
        return;
    }
    int max = arr[0];
    //获取最大数
    for (int i = 1;i<arr.length;i++){
        if (arr[i]>max){
            max = arr[i];
        }
    }
    int maxLength = String.valueOf(max).length();//得到最大数的位数
    int[][] bucket = new int[10][arr.length];//定义一个二维数组作为桶
    int[] bucketCount = new int[10];//定义一个数组存放每个桶中的数据个数
    //循环maxLength完成排序,个位直接对10取模,十位除以10在对10取模,依次便可得到每个位上的数值大小
    for (int i=0,n=1;i<maxLength;i++,n *=10){

        //将数据放入到对应的桶中
        for (int j=0;j<arr.length;j++){
            int val = arr[j] / n % 10;//得到每个位上的数值大小(个位,十位,百位)
            bucket[val][bucketCount[val]] = arr[j];//将数组值放入对应的桶中
            bucketCount[val]++;//对应的桶中数据个数加一
        }

        //将数据从桶中取出,放入到数组
        int index = 0;//建立一个索引,便于遍历
        for (int k=0;k<bucketCount.length;k++){
            if (bucketCount[k] != 0){//当桶中数据个数不等于零时遍历
                for (int m=0;m<bucketCount[k];m++){
                    arr[index++] = bucket[k][m];
                }
            }
            bucketCount[k] = 0;//将桶的数据个数重新置零
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/Mhang/p/12332681.html
今日推荐