题目
存在如下数组通过基数排序算法进行排序:
【12、451、35、21、4571、111、20、130、66、68、17、36】
实现代码
基数排序的原理就是先对个位进行排序,按序放入原数组,再对十位进行排序,再按序放入数组……
最终得到一个排好序的数组
(LSD算法)
以下是基数排序算法中的LSD算法实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| void radixSortLSD(int[] nums) { int min = Integer.MAX_VALUE; for (int num : nums) { min = Math.min(min, num); }
int offset = -min; for (int i = 0; i < nums.length; i++) { nums[i] += offset; }
int max = Integer.MIN_VALUE; for (int num : nums) { max = Math.max(max, num); }
int maxLen = 0; while (max > 0) { max /= 10; maxLen++; }
for (int k = 0; k < maxLen; k++) { countSort(nums, k); }
for (int i = 0; i < nums.length; i++) { nums[i] -= offset; } }
void countSort(int[] nums, int k) { int[] count = new int[10];
for (int num : nums) { int digit = (num / (int) Math.pow(10, k)) % 10; count[digit]++; }
for (int i = 1; i < count.length; i++) { count[i] += count[i - 1]; }
int[] sorted = new int[nums.length]; for (int i = nums.length - 1; i >= 0; i--) { int digit = (nums[i] / (int) Math.pow(10, k)) % 10; sorted[count[digit] - 1] = nums[i]; count[digit]--; }
for (int i = 0; i < nums.length; i++) { nums[i] = sorted[i]; } }
|
下面对部分代码进行讲解:
代码解释
代码片段一
1 2 3
| for (int i = 1; i < count.length; i++) { count[i] += count[i - 1]; }
|
计算“小于等于当前角标数值的数量”
比如:以个位数为例,并且 nums 总数为12个
计算之前:
个位数为 0 的数 : 2个
个位数为 1 的数 : 4个
个位数为 2 的数 : 1个
个位数为 3 的数 : 0个
个位数为 4 的数 : 0个
……
| i |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
| count(i) |
2 |
4 |
1 |
0 |
0 |
1 |
2 |
1 |
1 |
0 |
计算之后:
| i |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
| count(i) |
2 |
6 |
7 |
7 |
7 |
8 |
10 |
11 |
12 |
12 |
表示:
角标0:个位数上存在2个小于等于0的数据;
角标1:个位数上存在6个小于等于1的数据;
角标2:个位数上存在7个小于等于2的数据;
角标3:个位数上存在6个小于等于3的数据;
……
代码片段二
1 2 3 4 5 6 7 8
| int[] sorted = new int[nums.length]; for (int i = nums.length - 1; i >= 0; i--) { int digit = (nums[i] / (int) Math.pow(10, k)) % 10; sorted[count[digit] - 1] = nums[i]; count[digit]--; }
|
使用上面计算的 count数组进行排序,比如当前对 个位进行排序,遍历到nums[1],那么:
nums[1] = 451、digit = 1,那么count[1] = 6,sorted[6 - 1] = 451,count[1] = (6 - 1) = 5
| n |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
| sorted[n] |
|
|
|
|
|
451 |
12 |
|
|
|
|
|
下次遍历到num[3]
nums[3] = 21、digit = 1,那么count[1] = 5,sorted[5 - 1] = 21,count[1] = (5 - 1) = 4
| n |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
| sorted[n] |
|
|
|
|
21 |
451 |
12 |
35 |
|
|
|
|
以此类推,就能将 个位进行排序了