前言
lab13 实现了 counting sort 和 radix sort。
counting sort
目标:寻求一种使得 counting sort 能够处理负数的方法
[9, -1, 3, 5, -1, -2, 1]
思路:创建两个counts数组,一个统计正数的出现次数,记为countPos;一个统计负数的出现次数,记为countNe。然后根据这两个count数组,再创建两个starts数组,一个存储正数的位置,一个存储负数的位置。之后根据两个starts数组填充sorted数组即可。
一些注意事项:
- startsPos 存储正数位置时要加上一个等于负数个数的偏移量
- 注意处理负数时要加绝对值
下方是示例代码:
public static int[] betterCountingSort(int[] arr) {
// TODO make counting sort work with arrays containing negative numbers.
// find max
int max = Integer.MIN_VALUE;
for (int i : arr) {
max = max > i ? max : i;
}
// find min
int min = Integer.MAX_VALUE;
for (int i : arr) {
min = min < i ? min : i;
}
int neNum = 0;
int[] countPos = new int[max + 1];
int[] countNe = new int[Math.abs(min) + 1];
for (int i : arr) {
if (i >= 0) {
countPos[i]++;
} else {
countNe[Math.abs(i)]++;
neNum++;
}
}
int[] startsPos = new int[max + 1];
int[] startsNe = new int[Math.abs(min) + 1];
int pos = 0;
for (int i = 0; i < startsPos.length; i += 1) {
startsPos[i] = pos + neNum;
pos += countPos[i];
}
pos = 0;
for (int i = startsNe.length - 1; i >= 0; i -= 1) {
startsNe[i] = pos;
pos += countNe[i];
}
int size = arr.length;
int[] sorted = new int[size];
for (int i = 0; i < size; i += 1) {
int item = arr[i];
int place;
if (item >= 0) {
place = startsPos[item];
startsPos[item] += 1;
} else {
int absItem = Math.abs(item);
place = startsNe[absItem];
startsNe[absItem] += 1;
}
sorted[place] = item;
}
return sorted;
}
radix sort
目标:基于 LSD radix sort 算法按照字典序排序一个 ASCII 字符串数组,注意排序数字和字符串的区别(字符串长度不同时右边填充占位符)
字典序就是基于字符的ASCII值决定顺序。
50 48 97 98
48 50 97 98
0 2 a b
0 2 a b
50 49 97 98