基数排序(Radix Sort)
基数排序
基数排序(Radix Sort) 是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。
算法描述
- 取得数组中的最大数,并取得位数;
- arr为原始数组,从最低位开始取每个位组成radix数组;
- 对radix进行计数排序(利用计数排序适用于小范围数的特点);
时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好) | 空间复杂度 | 稳定性 |
---|---|---|---|---|
\(O(n*k)\) | \(O(n*k)\) | \(O(n*k)\) | \(O(n+k)\) | 稳定 |
例子
![](https://img2022.cnblogs.com/blog/2758160/202202/2758160-20220224090548200-1979379897.png)
动图演示
![](https://images.cnblogs.com/cnblogs_com/blogs/734424/galleries/2112342/o_220221110853_%E5%9F%BA%E6%95%B0%E6%8E%92%E5%BA%8F.gif)
代码
提示:对于位数不齐的元素可以用 “零” 补齐,分为补头和补尾
注意:这里使用的计数排序必须是稳定排序
Java
//ascii码的取值范围
public static final int ASCII_RANGE = 128;
public static String[] radixSort(String[] array, int maxLength) {
//排序结果数组,用于存储每一次按位排序的临时结果
String[] sortedArray = new String[array.length];
//从个位开始比较,一直比较到最高位
for (int k = maxLength - 1; k >= 0; k--) {
//计数排序的过程,分成三步:
//1.创建辅助排序的统计数组,并把待排序的字符对号入座,
//这里为了代码简洁,直接使用ascii码范围作为数组长度
int[] count = new int[ASCII_RANGE];
for (int i = 0; i < array.length; i++) {
int index = getCharIndex(array[i], k);
count[index]++;
}
//2.统计数组做变形,后面的元素等于前面的元素之和
for (int i = 1; i < count.length; i++) {
count[i] = count[i] + count[i - 1];
}
//3.倒序遍历原始数列,从统计数组找到正确位置,输出到结果数组
for (int i = array.length - 1; i >= 0; i--) {
int index = getCharIndex(array[i], k);
int sortedIndex = count[index] - 1;
sortedArray[sortedIndex] = array[i];
count[index]--;
}
//下一轮排序需要以上一轮的排序结果为基础,因此把结果复制给array
array = sortedArray.clone();
}
return array;
}
//获取字符串第k位字符所对应的ascii码序号
private static int getCharIndex(String str, int k) {
//如果字符串长度小于k,直接返回0,相当于给不存在的位置补0
if (str.length() < (k + 1)) {
return 0;
}
return str.charAt(k);
}