- 代码:
/**
* @Description:
* 一种多关键字的排序算法,可用桶排序实现。
* 算法思想:
* 取得数组中的最大数,并取得位数;
* arr为原始数组,从最低位开始取每个位组成radix数组;
* 对radix进行计数排序(利用计数排序适用于小范围数的特点)
* @Author: chong
* @Data: 2021/6/22 3:23 下午
*/
public class RadixSortTemplate {
/**
* 基数排序,仅支持非负数
* @param nums
*/
public void radixSort(int[] nums){
if (nums == null || nums.length < 2)
return;
radixSort(nums, 0, nums.length - 1, maxBits(nums));
}
/**
* 真正的入桶出桶过程
* @param nums 待排序数组
* @param begin 数组中要排序部分的初始点
* @param end 数组中要排序部分的结束点
* @param digit 数组中最大值的位数
*/
public void radixSort(int[] nums, int begin, int end, int digit){
final int radix = 10; // 十进制的基数
int[] count = new int[radix]; // 词频表count的大小为radix,即0-9
int[] bucket = new int[end - begin + 1]; // 辅助数组,长度是要排序部分的长度、
for (int d = 1; d <= digit; d++){ // 根据最大数字的位数来决定入桶出桶的次数
for (int i = 0; i < radix; i++) // 每次入桶出桶过程前先把count置0
count[i] = 0;
for (int i = begin; i <= end; i++){
int j = getDigits(nums[i], d); // 拿到nums中每个数字第d位上的值
count[j]++; // 对应count词频表上的值++,更新词频表
}
// 对词频表进行加工,使其中保存的值代表比第i位小于等于的数字有几个
// count[0] 指当前位(d位)是0的数字有几个
// count[1] 指当前位(d位)是0和1的数字有几个
// count[2] 指当前位(d位)是0、1和2的数字有几个
// count[i] 指当前位(d位)是0~i的数字有几个
for (int i = 1; i < radix; i++){
count[i] = count[i] + count[i - 1];
}
// 这里优化掉入桶出桶的过程,直接将出桶的结果存在bucket中
for (int i = end; i >=begin; i--){
int j = getDigits(nums[i], d);
bucket[count[j] - 1] = nums[i];
count[j]--;
}
// 将辅助数组bucket的结果存回nums
for (int i = begin, j = 0; i <= end; i++, j++){
nums[i] = bucket[j];
}
}
}
/**
* 用于取得待排序数组中最大数字的位数
* 如:数组[23, 43, 2, 134]中最大值位134,输出其位数3
* @param nums
* @return
*/
public int maxBits(int[] nums){
int maxValue = Integer.MIN_VALUE;
for (int num : nums)
maxValue = Math.max(maxValue, num);
int res = 0;
while (maxValue != 0){
maxValue /= 10;
res++;
}
return res;
}
/**
* 用于取得数字x的从最低位开始的第digit位的值
* 如:数字123的第2位,123 / 10 ^(2 - 1) % 10 = 12 % 10 = 2
* @param x
* @param digit
* @return
*/
public static int getDigits(int x, int digit){
return (x / ((int) Math.pow(10, digit - 1))) % 10;
}
@Test
public void test(){
int[] nums = {5, 2, 72, 45, 23, 63, 5, 24, 12};
radixSort(nums);
System.out.println(Arrays.toString(nums));
}
}