• 算法


    要点:利用空间换时间,有桶排序的思想,按照基数规则转换,使空间开销较小,但理解起来比计数排序复杂的多。

     1 import java.util.Random;
     2 
     3 public class RadixSort {
     4 
     5     public void sort(int arr[]) {
     6         int max = arr[0];
     7         for (int i = 1; i < arr.length; i++) {
     8             if (arr[i] > max) {
     9                 max = arr[i];
    10             }
    11         }
    12         // 计数
    13         int[] bucketArr;
    14         // 输出
    15         int[] outputArr = new int[arr.length];
    16         // 根据最大值求指数
    17         int exp = (int) Math.pow(10, String.valueOf(max).length() - 1);
    18         for (int i = 1; i <= exp; i *= 10) {
    19             bucketArr = new int[10];
    20             for (int j = 0; j < arr.length; j++) {
    21                 int index = arr[j] / i % 10;
    22                 bucketArr[index]++;
    23             }
    24             printArr(bucketArr, " => 计数bucket");
    25             // 转换 => 见转换说明
    26             for (int j = 1; j < 10; j++) {
    27                 bucketArr[j] += bucketArr[j - 1];
    28             }
    29             printArr(bucketArr, " => 转换bucket");
    30             // 根据转换后的bucket数组,将原数组的值映射到output数组 => 见映射说明
    31             // 注意采用的是倒序遍历 => 见倒序说明
    32             for (int j = arr.length - 1; j >= 0; j--) {
    33                 int index = arr[j] / i % 10;
    34                 int outputIndex = bucketArr[index]--;
    35                 outputArr[outputIndex - 1] = arr[j];
    36             }
    37             printArr(outputArr," => output数组");
    38             for (int j = 0; j < outputArr.length; j++) {
    39                 arr[j] = outputArr[j];
    40             }
    41         }
    42     }
    43 
    44     private void printArr(int[] arr, String message) {
    45         for (int n : arr) {
    46             System.out.print(n + ",");
    47         }
    48         System.out.println(message);
    49     }
    50 
    51     public static void main(String[] args) {
    52         int capacity = 10;
    53         int[] arr = new int[capacity];
    54         for (int i = 0; i < capacity; i++) {
    55             arr[i] = new Random().nextInt(500);
    56         }
    57         RadixSort rs = new RadixSort();
    58         rs.printArr(arr, " => 原数组");
    59         rs.sort(arr);
    60         rs.printArr(arr, " => 排序后数组");
    61     }
    62 
    63     /**
    64      * 转换说明:
    65      * 0,1,0,0,2,4,0,2,1,0, => 计数bucket
    66      * 转换公式:bucekt[i] += bucket[i - 1]
    67      * 0,1,1,1,3,7,7,9,10,10, => 转换bucket
    68      * 说白了就是为了统计到[i]位置,bucket获取的元素数
    69      *
    70      * 映射说明:
    71      * 45,5,21,245,454,204,138,137,77,445, => 原数组
    72      * 0,1,1,1,3,7,7,9,10,10, => 转换bucket
    73      * 当前的exp是1:
    74      * 首先计算原数组中的值在bucket哪个位置:=> index = 445 / 1 % 10 = 5
    75      * 找到bucket[5]对应的值是7,7代表的是个数,因此要减去1才代表下标。
    76      * out[6] = 445
    77      * 21,454,204,45,5,245,445,137,77,138, => output数组
    78      *
    79      * 倒序说明:
    80      * 204,5,21,137,138,45,245,445,454,77, => 按照十位已经排好序了
    81      * 此时,数组十位是有序状态,【从小到大】。
    82      * 4,2,2,0,2,0,0,0,0,0, => 计数bucket => 其中5,21,45,77在0坐标处计数,为4
    83      * 4,6,8,8,10,10,10,10,10,10, => 转换bucket
    84      * 求百位时,所有的个位和十位在求对应的bucket位置时都是0。
    85      * 如果按正序遍历,就相当于按照从大到小的顺序填入output数组。
    86      * 如正序遍历,拿到5,求得bucket坐标是0,读取值4,坐标为3,output[3]=5,读取值-1
    87      * 继续遍历到21,求得bucket坐标是0,读取值3,坐标为2,output[2]=21,读取值-1
    88      * 顺序反了,因此需要倒序遍历。
    89      *
    90      * 利用空间换时间,但是利用了转换规则,使空间开销较小
    91      * => 遍历了exp * (4m + 10) 次
    92      * => 时间复杂度O(n) => exp还是有限的
    93      * => 稳定性:稳定 => 都是整数
    94      *
    95      */
    96 
    97 }
  • 相关阅读:
    微信小程序踩坑(二)——微信小程序recorderManager和innerAudioContext相关
    log4j:WARN Please initialize the log4j system properly解决办法
    如何跳过登录验证码
    Fiddler Mock长度变化的response不成功
    解决Chrome浏览器访问https提示“您的连接不是私密连接”的问题
    Fiddler抓不到https的解决办法
    互联网项目流程
    测试人员参与线下问题处理须知
    Mac下安装证书fiddlerRoot.cer
    MySQL存储过程中实现执行动态SQL语句
  • 原文地址:https://www.cnblogs.com/SamNicole1809/p/12809719.html
Copyright © 2020-2023  润新知