思路:
1.先获取数组中的最大值,计算出最大值的位数 2.然后大循环需要按照位数来计算,有多少位,就大循环多少次 3.在循环的过程中 大循环(最大数的位数的次数当做条件) a. 使用一个数组count 记录数组中的每一位数出现的次数 b. 将count数组中的出现次数合并起来 c. 从后往前遍历数组,再次获取数组中每一位数出现的次数,然后将其放入help数组中 怎么放? 根据count中的当前数的出现次数,放入到-1的位置,这样放好之后,和出桶的顺序是一致的 d. 遍历help数组,将每一次的值放入到arr数组中
//参数;传递一个数组
public static void radixSort(int[] arr) {
//如果数组为空 或者数组内只要一个值 则不需要排序
if (arr == null || arr.length < 2) {
return;
}
//调用方法获取数组中的最大值
int radix = getRadix(arr);
//获取到最大值后,调用方法 进行排序
doRadixSort(arr, 0, arr.length - 1, radix);
}
//设计一个方法 在给定的区间范围内(begin -- end)做基数排序
//参数:需要排序的数组 起始位置 终止位置 最大值的位数
private static void doRadixSort(int[] arr, int begin, int end, int radix) {
//大循环 控制轮次 以最大值的位数作为循环次数 循环radix次
//存储每一次出桶的结果 长度为数组中元素的个数长度
int[] help = new int[end - begin + 1];
//记录每一位的数
int eachSingleNum = 0;
for (int i = 1; i <= radix; i++) {
//存放每个数出现次数的数组 因为每一位数只能是从0-9 所以数组只需要10个长度
int[] count = new int[10];
//首先:循环将每个数的每一位数都记录下来,存放到一个额外的数组中 count[]
//循环条件:从给定的起始位置和终止位置来做一个排序
int j = 0;
for (j = begin; j <= end; j++) {
//将每一个数进行计算 求出其每一位数
eachSingleNum = getSingleNum(arr[j], i);
//将对应的位数的位置上的值加1
count[eachSingleNum]++;
}
int k = 0;
//其次:在每个数的位数出现次数都找出来之后,将count上的次数值合并起来
//即: 小于等于x的出现次数都合并到x身上
for (k = 1; k < count.length; k++) {
count[k] = count[k - 1] + count[k];
}
//再者:从后往前遍历数组,再次获取每个数的每一位数,然后在count中找到他的位置再-1,放到help中
for (k = end; k >= begin; k--) {
eachSingleNum = getSingleNum(arr[k], i);
help[count[eachSingleNum] - 1] = arr[k];
//对应的count中的出现次数在存入值之后也要减1
count[eachSingleNum]--;
}
//最后:遍历help数组 将出桶的值放入到arr数组中
//因为help需要从0开始放,而arr是从给定的起始范围开始放,所以需要两个条件
//k = 0 从help中取值的索引
//j = L 放入arr中的索引
for (k = 0, j = begin; k < help.length; k++) {
arr[j] = help[k];
j++;
}
}
}
//设计一个方法 求给定数在当前radix上的单个位数
private static int getSingleNum(int curNum, int radix) {
//用radix来控制第几位
/* 设curNum = 129
radix 1 2 3
需求: /10^0%10 /10^1%10 /10^2%10
规律:(curNum / 10^radix-1) % 10;
*/
//按照以上规律 可得公式
return ( (curNum / ((int) Math.pow(10, radix - 1)) ) % 10);
}
//设计一个方法 获取数组中的最大值,并返回他的位数
private static int getRadix(int[] arr) {
//先初始化一个最小值
int max = Integer.MIN_VALUE;
//循环找出数组中的最大值
for (int i = 0; i < arr.length; i++) {
max = arr[i] > max ? arr[i] : max;
}
//用一个变量来记录最大值的位数
int count = 0;
//最大值找出来后 计算出这个最大值的位数
while (max != 0) {
//第一次进来直接加上一位,然后如果除以10不等于0的话,再加上一位,依次循环
count++;
max /= 10;
}
return count;
}