- 基数排序通过对数据不同位的数字大小进行分装再实现排序,是一种非比较排序,其实现分为MSD和LSD两种方式,其中LSD部分代码包含计数排序(点击查看计数排序)的思想。
代码
LSD实现:
def lsd_radix(arr):
Max = max(arr)
exponent = 1
while Max // exponent > 0:
count_sort(arr, exponent)
exponent *= 10
return arr
def count_sort(arr, exponent):
count = [0] * 10
temporary = [0]*len(arr) # 这里要搞清计数列表(count)和赋值列表(temporary)区别,大小不同
for i in arr:
index = i // exponent
count[index % 10] += 1
for i in range(1, 10):
count[i] += count[i - 1]
for i in reversed(arr): # 注意逆序
index = i // exponent
temporary[count[index % 10] - 1] = i
count[index % 10] -= 1
# 使用for循环更加简洁
n = len(arr)-1
while n >= 0:
arr[n] = temporary[n]
n -= 1
输入:
[170, 45, 75, 90, 802, 24, 2, 66, 66]输出:
- [2, 24, 45, 66, 66, 75, 90, 170, 802]
MSD实现:
def msd_radix(arr):
def msd(arr,exponent):
if len(arr) <= 1 or exponent == 0:
return arr
count = [[] for _ in range(10)] # 分桶
temporary = []
for i in arr:
index = i // exponent
count[index % 10].append(i) # 注意此处,避免写错
for i in count:
if i:
temporary.extend(msd(i,exponent//10)) # '//'用来确保列表索引为整数
return temporary
Max = max(arr)
exponent = 1
while Max // exponent > 10:
exponent *= 10
return msd(arr,exponent)
输入:
[170, 45, 75, 90, 802, 24, 2, 66, 66]输出:
- [2, 24, 45, 66, 66, 75, 90, 170, 802]
MSD(Most Significant Digit)和 LSD(Least Significant Digit)基数排序是两种基数排序方法,它们在处理数据时有一些关键的区别:
1. 排序方法
-
MSD(Most Significant Digit)基数排序:
- 排序方式:从最高位(最重要的位)开始排序,然后逐步处理到低位(次重要的位)。
- 递归特性:通常采用递归方式处理每一位。
- 应用场景:适合处理具有较多位数的数据,特别是在位数较多时更为高效。
-
LSD(Least Significant Digit)基数排序:
- 排序方式:从最低位(最不重要的位)开始排序,然后逐步处理到高位(最重要的位)。
- 迭代特性:通常采用迭代方式处理每一位。
- 应用场景:适合处理数据位数较少的情况,简单且易于实现。
2. 处理顺序
-
MSD:
- 处理数据时先处理最高位,逐步递归处理到最低位。例如,对于整数 345 和 789,MSD 会先按百位(3 和 7)排序,然后处理十位和个位。
-
LSD:
- 处理数据时从最低位开始,例如对于整数 345 和 789,LSD 会先按个位(5 和 9)排序,然后处理十位和百位。
3. 时间复杂度
-
MSD:
- 在处理每一位时,复杂度主要取决于位数和每个桶内的排序。总体时间复杂度为 O(n⋅k),其中 n 是元素个数,k是最大位数。
- MSD 的递归深度取决于位数,因此在处理大数据时可能会有更高的内存开销。
-
LSD:
- 对每一位进行排序,通常时间复杂度为 O(n⋅k)。LSD 方法不涉及递归,相对内存开销较小。
4. 内存使用
-
MSD:
- 由于递归调用和桶的使用,MSD 可能需要更多的内存来存储中间结果。
-
LSD:
- 由于使用迭代方法,LSD 通常需要较少的内存,适合内存有限的环境。
5. 实现复杂性
-
MSD:
- 实现上可能会更复杂,需要处理递归和多级桶排序。
-
LSD:
- 实现上通常较为简单,因为它只是逐位进行排序,不涉及递归。
总结
- MSD 基数排序 从最高位开始处理,通常适合位数较多的数据。
- LSD 基数排序 从最低位开始处理,通常适合位数较少的数据,实施较简单。