基本思想
假如来了一个混乱数组org ,我们需要将它排好序。我们做如下操作。
- 先得到该数组中最大的那个数MAX。
- 创建一个数组
ans ,该数组的长度就是MAX。 - 接下来遍历混乱数组
org ,ans[org[i]]=org[i]; 。
以上的操作很简单,我们可以轻易的看出其缺点就是太浪费空间。 那么基数排序,则是对以上操作进行了优化。基数排序我们做如下操作。
- 创建桶数组,其长度为20(考虑正负数)。
- 接下来循环,第一轮是取每个数字的个位数,在桶数组对应位置+1。
- 根据桶的个数生成位置。
- 获取位置,更新原数组。
- 第二轮循环开始,这次是取每个数字的百位数,重复以上操作。
- 接下来依次类推,循环次数为原数组最大值的位数。
图示
以下动图取自网络
代码模板
public void get() {
int[] arr = new int[]{17, -13, 20, -7, 2, 17, 12};
radixSort(arr);
for (int i : arr) {
System.out.println(i);
}
}
public void radixSort(int[] arr) {
int[] tmp = new int[arr.length];
int n = 1;
int[] bin = new int[20];
while (true) {
for (int val : arr) {
int j = (val / n) % 10;
if (j >= 0) {
bin[j]++;
} else {
bin[10 - j]++;
}
}
if (bin[0] == arr.length) break;
for (int i = 18; i > 10; i--) {
bin[i] += bin[i + 1];
}
bin[0]+=bin[11];
for (int i = 1; i < 10; i++) {
bin[i] += bin[i - 1];
}
for (int i = tmp.length - 1; i >= 0; i--) {
int j = (arr[i] / n) % 10;
if (j >= 0) {
bin[j]--;
tmp[bin[j]] = arr[i];
} else {
bin[10 - j]--;
tmp[bin[10 - j]] = arr[i];
}
}
System.arraycopy(tmp, 0, arr, 0, tmp.length);
n *= 10;
Arrays.fill(bin, 0);
}
}
-
时
间
复
杂
度
为
O
(
d
(
n
+
r
)
)
,
空
间
复
杂
度
为
O
(
n
)
时间复杂度为O(d(n+r)),空间复杂度为O(n)
时间复杂度为O(d(n+r)),空间复杂度为O(n)
|