20 -- 排序算法之基数排序

 

 

 

 举例说明:

1、第一轮:按照每个元素的 个 位取出,然后将这个数放在对应的桶(数组)中;在按照这个桶的顺序,放入原来的数组中 -->

 

 2、第二轮:按照每个元素的  位取出, -->

 

  3、第三轮:按照每个元素的  位取出, -->

 总结:从中可以看到 --> 排序的次数 等于 待排序中的最大位数的个数

 代码实现:

  1 import java.util.Arrays;
  2 
  3 //基数排序(桶排序)
  4 public class RadixSort {
  5 
  6     public static void main(String[] args) {
  7         int[] arr = {53,3,542,748,14,214};
  8         radixSort2(arr);
  9     }
 10     
 11     public static void radixSort(int[] arr) {
 12         System.out.println("第一轮:针对每个元素的个位数进行排序");
 13         //第一轮:针对每个元素的个位数进行排序
 14         //定义10个桶(基数为0~9),为了防止极端情况(基数全部一样),每个桶的大小与数组中元素的个数一样【空间换时间】
 15         int[][] bucket = new int[10][arr.length];
 16         
 17         //记录每个桶中的位数
 18         int[] countOfBucket = new int[10];
 19         //放置
 20         int digitOfEmement = 0;
 21         for(int j = 0; j < arr.length; j ++) {
 22             digitOfEmement = arr[j] % 10;
 23             bucket[digitOfEmement][countOfBucket[digitOfEmement]] = arr[j];
 24             countOfBucket[digitOfEmement] ++;
 25         }
 26         
 27         //依次取出每个桶中的数据放入到数组中
 28         int index = 0;
 29         for(int i = 0; i < bucket.length; i++) {
 30             for(int j = 0; j < countOfBucket[i]; j++) {
 31                 arr[index] = bucket[i][j];
 32                 index ++;
 33             }
 34             //清空记录每个桶装的数据的个数,用于下次使用
 35             countOfBucket[i] = 0;
 36         }
 37         System.out.println(Arrays.toString(arr));
 38     
 39         System.out.println("第二轮:针对每个元素的十位数进行排序");
 40         for(int j = 0; j < arr.length; j++) {
 41             digitOfEmement = arr[j] / 10 % 10;
 42             bucket[digitOfEmement][countOfBucket[digitOfEmement]] = arr[j];
 43             countOfBucket[digitOfEmement] ++;
 44         }
 45         
 46         index = 0;
 47         for(int i = 0; i < bucket.length; i++) {
 48             for(int j = 0; j < countOfBucket[i]; j++) {
 49                 arr[index] = bucket[i][j];
 50                 index ++;
 51             }
 52             countOfBucket[i] = 0;
 53         }
 54         System.out.println(Arrays.toString(arr));
 55         
 56         
 57         System.out.println("第三轮:针对每个元素的百位数进行排序");
 58         for(int j = 0; j < arr.length; j++) {
 59             digitOfEmement = arr[j] / 100 % 10;
 60             bucket[digitOfEmement][countOfBucket[digitOfEmement]] = arr[j];
 61             countOfBucket[digitOfEmement] ++;
 62         }
 63         
 64         index = 0;
 65         for(int i = 0; i < bucket.length; i++) {
 66             for(int j = 0; j < countOfBucket[i]; j++) {
 67                 arr[index] = bucket[i][j];
 68                 index ++;
 69             }
 70             countOfBucket[i] = 0;
 71         }
 72         System.out.println(Arrays.toString(arr));
 73         
 74      }
 75 
 76     
 77     //总结出规律得出
 78     public static void radixSort2(int[] arr) {
 79         //定义十个桶,每个桶的大小为数组的长度
 80         int[][] bucket = new int[10][arr.length];
 81         
 82         //一维数组:记录每个桶中中放置的数据的个数
 83         int[] countOfBucket = new int[10];
 84         int max = arr[0]; //假设第一个数为数组中最大位数个数
 85         for(int i = 1; i < arr.length; i++) {
 86             if (arr[i] > max) {
 87                 max = arr[i];
 88             }
 89         }
 90         
 91         int maxLength = (max + "").length();
 92         
 93         int digitOfElemnt = 0;
 94         int index = 0;
 95         //i:根据最大位数循环
 96         //radix : 每次以...为基准【个、十、百、千 ...】
 97         for(int i = 0, radix = 1; i < maxLength; i++, radix *= 10) {
 98             for(int j = 0; j < arr.length; j++) {
 99                 //取出基准数
100                 digitOfElemnt = arr[j] / radix % 10; 
101                 //根据基准数入桶
102                 bucket[digitOfElemnt][countOfBucket[digitOfElemnt]] = arr[j];
103                 countOfBucket[digitOfElemnt] ++;
104             }
105             
106             index = 0;
107             //从0~9遍历桶,依次取出各个元素重新装入原数组中
108             for(int k = 0; k < bucket.length; k ++) {
109                 for(int l = 0; l < countOfBucket[k]; l ++) {
110                     arr[index] = bucket[k][l];
111                     index ++;
112                 }
113                 countOfBucket[k] = 0;
114             }
115             System.out.println("第" + (i+1) + "次:" + Arrays.toString(arr));
116         }
117         
118     }
119     
120 }

运行结果:

 

 总结【注意】:

从基数排序(桶排序)的示意图和代码实现部分可以看出,基数排序是典型的用空间换取时间的例子,并且它不适合做负数的排序。

posted @ 2022-10-08 21:13  羽梦齐飞  阅读(24)  评论(0编辑  收藏  举报