基数排序(Radix Sort)

基数排序

基数排序(Radix Sort) 是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。

算法描述

  1. 取得数组中的最大数,并取得位数;
  2. arr为原始数组,从最低位开始取每个位组成radix数组;
  3. 对radix进行计数排序(利用计数排序适用于小范围数的特点);
时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
\(O(n*k)\) \(O(n*k)\) \(O(n*k)\) \(O(n+k)\) 稳定

例子

动图演示

代码

提示:对于位数不齐的元素可以用 “零” 补齐,分为补头和补尾

注意:这里使用的计数排序必须是稳定排序

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);
}
posted @ 2022-02-24 09:19  morning-start  阅读(23)  评论(0编辑  收藏  举报