算法过程:
- 1、初始化:构造一个10*n的二维数组,一个长度为n的数组用于存储每次位排序时每个桶子里有多少个元素。
- 2、循环操作:从低位开始(我们采用LSD的方式),将所有元素对应该位的数字存到相应的桶子里去(对应二维数组的那一列)。然后将所有桶子里的元素按照桶子标号从小到大取出,对于同一个桶子里的元素,先放进去的先取出,后放进去的后取出(保证排序稳定性)。这样原数组就按该位排序完毕了,继续下一位操作,直到最高位排序完成。
- 下面给出一个实例帮助理解:
- 我们现有一个数组:73, 22, 93, 43, 55, 14, 28, 65, 39, 81
- 下面是排序过程(二维数组里每一列对应一个桶,因为桶空间没用完,因此没有将二维数组画全):
1. 按个位排序
- 按第一位排序后数组结果:
- 81,22,73,93,43,14,55,65,28,39
- 可以看到数组已经按个位排序了。
2. 根据个位排序结果按百位排序
- 取出排序结果:
- 14,22,28,39,43,55,65,73,81,93
- 可以看到在个位排序的基础上,百位也排序完成(对于百位相同的数子,如22,28,因为个位已经排序,而取出时也保持了排序的稳定性,所以这两个数的位置前后是根据他们个位排序结果决定的)。因为原数组元素最高只有百位,原数组也完成了排序过程。
代码:
public class RadixSort {
private static void radixSort(int[] arr, int d) {
int n = 1; //代表位数对应的数:1,10,100...
int k = 0; //保存每一位排序后的结果用于下一位的排序输入
int length = arr.length;
int[][] bucket = new int[10][length]; //排序桶用于保存每次排序后的结果,这一位上排序结果相同的数字放在同一个桶里
int[] order = new int[10]; //用于保存每个桶里有多少数字
while (n < d) {
for (int num : arr) { //将数组arr里的每个数字放在相应的桶里
int digit = (num / n) % 10;
bucket[digit][order[digit]] = num;
order[digit]++;
}
for (int i = 0; i < 10; i++) { //将前一个循环生成的桶里的数据覆盖到原数组中用于保存这一位的排序结果
if (order[i] != 0) { //这个桶里有数据,从上到下遍历这个桶并将数据保存到原数组中
for (int j = 0; j < order[i]; j++) {
arr[k] = bucket[i][j];
k++;
}
}
order[i] = 0; //将桶里计算器置0,用于下一次位排序
}
n *= 10;
k = 0; //将k置0,用于下一轮保存位排序结果
}
}
public static void main(String[] args) {
int[] arr = {73, 22, 93, 43, 55, 14, 28, 65, 39, 81};
// 100是指所有数只是在百位以下
radixSort(arr, 100);
for (int num : arr) {
System.out.print(num + " ");
}
}
}