基数排序(Radix Sort)是桶排序的扩展,它的基本思想是:将整数按位数切割成不同的数字,然后按每个位数分别比较。
具体做法是:将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
如果定义看的模糊,请看下面图解就可以轻而易举看懂。
假定arr数组中的元素为{22,0,4,91,551,3,52,312,94,321}。先找到最大的数为551三位,所以定义length = 3。图为3次排序过程(字写得丑,请见谅)

第一轮后arr数组为{0,91,551,321,22,52,312,3,4,94},下面进行第二轮
第二轮后arr数组为{0,3,1,312,321,22,551,52,91,94},下面进行第三轮

最后得出有序数组为{0,3,4,22,52,91,94,312,321,551}.
代码如下
public static void radixSort(int[] arr) {
//求最大位的个数,将最大数转换为字符串求其长度即为基数排序循环次数。
int max = arr[0];
for(int i = 1 ; i < arr.length ; i++) {
max = max > arr[i] ? max : arr[i];
}
int length = (max+"").length();
//创建一个二维数组用于每次存放排序的数,
//10行因为余数可能为0-9的任意一个
//列数为arr.length最坏情况下所有数的余数均相同
int[][] bucket = new int[10][arr.length];
//创建一个counts计数数组用于记录bucket数组中每个位存放了多少个元素
//大小与bucket的行数相对应
int[] counts = new int[10];
for(int i = 0 , x = 1; i < length ; i++,x*=10) {
//一次次将arr数组中的数放入bucket中(根据余数判断)
for(int j = 0 ; j < arr.length ; j++) {
//remainder记录每个数的余数
int r = arr[j] / x % 10;
bucket[r][counts[r]] = arr[j];
//每次向bucket[r]存入一个数该数的大小+1
counts[r] ++;
}
//定义index用于将bucket中的数据放回到arr数组。
int index = 0;
//循环将bucket中的数放回arr数组
for(int j = 0 ; j < 10 ; j++) {
//如果该桶的某一位有数,则counts[j]必大于0
if(counts[j] != 0) {
//将桶中的数按序放入arr
for(int k = 0 ; k < counts[j] ; k++) {
arr[index] = bucket[j][k];
index++; //不能忘记每次加数后index递增。
}
//将counts[j]清零,用于下次循环
counts[j] = 0;
}
}
}
}
测试代码
分别用随机数生成若干个位,十位,百位的数
public static void main(String[] args) {
int []arr = new int[10];
for (int i = 0 ; i < 3 ; i++) {
arr[i] = (int)(Math.random()*10);
}
for (int i = 3 ; i < 7 ; i++) {
arr[i] = (int)(Math.random()*100);
}
for (int i = 7 ; i < 10 ; i++) {
arr[i] = (int)(Math.random()*1000);
}
radixSort(arr);
System.out.println(Arrays.toString(arr));
}
结果如下:
希望能帮助大家理解基数排序。
本文详细介绍了基数排序算法的工作原理及其实现过程。通过示例展示如何将整数按位数切割并进行排序,最终得到有序序列。附带完整Java实现代码及测试案例。
76

被折叠的 条评论
为什么被折叠?



