基数排序 LSD py
链接:https://www.nowcoder.com/questionTerminal/1e68ccb2cbc74c3d9e0dea0c568789b8
设数组S[]={154,265,146,31,213,14,157,189,91,10,111,123},采用最低位优先(LSD)基数排序将S排列成升序序列,第1趟分配收集后元素14之前,之后紧邻的元素是()
第1趟分配收集后的结果为:10,31,91,111,213,123,154,14,265,146,157,189
基数排序可以排序整数、字符。原理是补齐长度,按位比较,按照比较方向可以分为低位优先(Least Significant Digit first, LSD)和高位优先 (MSD)。
平均时间复杂度:O(n*k),k是最大位数
原理
这里以比较整形数字为例:
- 确定最大数的位数:首先找出待排序数中的最大数,以确定最大位数。
- 初始化桶:创建10个桶(0-9),每个桶用于存放对应位数的数字。
- 分配数字到桶:从 最低位/最高位 开始,遍历每个数字,根据当前位的数值将其放入相应的桶中。
- 收集桶中数字:按顺序收集桶中的数字,放回原数组。
- 重复过程:对每一位重复上述分配和收集过程,直到 最高位/最低位。
低位优先
def radix_sort(arr):
# 找出最大数以确定最大位数
max_num = max(arr)
# 计算最大数的位数
max_digits = len(str(max_num))
# 初始化桶
buckets = [[] for _ in range(10)]
# 从最低位开始,对每一位进行排序
for digit in range(max_digits):
# 分配数字到桶
for num in arr:
# 计算当前位的数值
current_digit = (num // (10 ** digit)) % 10
# 将数字放入相应的桶中,相同数字放在同一个桶,列表可以保证顺序
buckets[current_digit].append(num)
# 收集桶中的数字,放回原数组
# arr = [num for bucket in buckets for num in bucket] # 不好理解
arr.clear()
for bucket in buckets:
arr.extend(bucket)
# 清空桶,为下一次分配做准备
buckets = [[] for _ in range(10)]
print(f"DEBUG digit: {digit}, arr: {arr}")
return arr
# 测试数组
arr = [154, 265, 146, 31, 213, 14, 157, 189, 91, 10, 111, 123]
# 执行基数排序
sorted_arr = radix_sort(arr)
# 打印排序后的数组
print(sorted_arr)
DEBUG digit: 0, arr: [10, 31, 91, 111, 213, 123, 154, 14, 265, 146, 157, 189]
DEBUG digit: 1, arr: [10, 111, 213, 14, 123, 31, 146, 154, 157, 265, 189, 91]
DEBUG digit: 2, arr: [10, 14, 31, 91, 111, 123, 146, 154, 157, 189, 213, 265]
[10, 14, 31, 91, 111, 123, 146, 154, 157, 189, 213, 265]