基数排序是通过数据情况排序的一种,它可根据键值的部分资讯进行排序,达到排序的作用
例如在数组中有值:56,124,77,253
首先对个位进行排序,根据计数算法思想得出的结果为:253,124,56,77
然后再对十位进行排序,结果为:124,253,56,77(根据先进先出原则将253排在56之前)
最后对百位进行排序(不足百位补0),结果为:056,077,124,253(先进先出,56在77之前)
以上每次排序都用到了计数排序思想,先理解了计数排序后就比较容易理解基数排序
下面附上代码与图解,可以使用少量数据debug分析判断,更容易理解
package com.mrz.test;
import java.util.Arrays;
/*
* 2022-04-09
* mrz
* 基数排序
*/
public class BaseSort {
public static void main(String[] args) {
int[] arr = {146,398,198,78,66,221};
int[] result = sort(arr);
System.out.println(Arrays.toString(result));
}
public static int[] sort(int[] arr) {
// TODO Auto-generated method stub
int[] result = new int[arr.length]; //开辟一个与原数组等大小的辅助数组
int[] count = new int[10]; //开辟一个桶数组
int max = GetMax(arr); //获取数组中最大值
int digit = (int)Math.log10(max)+1; //获取最大值的位数
for(int i = 0;i < digit;i++) { //最大值位数决定循环次数
int division = (int) Math.pow(10, i); //计算10的i次方,用以确定对个位或是十位等进行求余
//System.out.println(division);
for(int j = 0;j < arr.length;j++) {
int num = arr[j]/division % 10; //分别对个位,十位和百位进行求余操作
System.out.print(num + " "); //打印值,确定位数
count[num]++; //计数,将出现的值对应的桶下标自增
}
System.out.println();
System.out.println(Arrays.toString(count)); //此次打印是将数组中数字对应的下标值出现的次数
for(int m = 1;m < count.length;m++) {
count[m] = count[m] + count[m-1]; //将出现的数字的频数相加形成新的数组
}
System.out.println(Arrays.toString(count)); //这次的打印是把所有出现的频数累加
for(int n = arr.length-1;n>=0;n--) {
int num = arr[n]/division % 10; //此计算是用于确定排序的位数(数字的个位,十位或百位等)
result[--count[num]] = arr[n]; //将数组中的值按照从右向左的顺序放入辅助数组中
}
System.arraycopy(result, 0, arr, 0, arr.length); //把辅助数组的值复制到原数组中
Arrays.fill(count, 0); //清空count数组
}
return result;
}
//获取最大值
private static int GetMax(int[] arr) {
// TODO Auto-generated method stub
int max = arr[0];
for(int i = 0;i < arr.length;i++) {
if(max < arr[i]) {
max = arr[i];
}
}
return max;
}
}
图解: