基本算法之基数排序(Radix Sort)
基本算法—06、基数排序(Radix Sort)算法
。往期请看选择排序,插入排序,归并排序,快速排序等等都发布的!欢迎大家批评指正!
0、前言
评判一个算法的好坏的标准:
- 时间复杂度
- 空间复杂度
1、基数排序算法是什么?
基数排序(Radix Sort)属于“分配式排序”,又称为“桶子法”
将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
时间复杂度:O(d(r+n))
- d 为采取的基数,
- r为堆数
在某些时候,基数排序法的效率高于其他的稳定性排序
1.1基数排序有两种方法:
- MSD (Most significant digital)(主位优先法):从高位开始进行排序
先按k1排序分组, 同一组中记录, 关键码k1相等,再对各组按k2排序分成子组, 之后, 对后面的关键码继续这样的排序分组, 直到按最次位关键码kd对各子组排序后. 再将各组连接起来,便得到一个有序序列。MSD方式适用于位数多的序列。
- LSD (Least significant digital)(次位优先法):从低位开始进行排序
先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。LSD方式适用于位数少的序列。
2、算法过程图解
3、代码实现
代码如下(示例01):
"""
Radix Sort 基数排序
“分配式排序”,又称为“桶子法”
时间复杂度:O(d(r+n))
"""
LSD Radix Sort
def radix_sort(alist):
# 创建十个桶子
busket = [[] for i in range(10)]
# 外层循环的次数就是这里面数值最大的位数
for i in range(len(str(max(alist)))):
# 循环里面的每一个数组,添加到对应的数组里面
for item in alist:
busket[item//(10**i)%10].append(item)
# print(busket)
i = 0
# 然后把放入的数组一次弹出
for item2 in busket:
# 这里用while,不能用if,因为里面可能有好几个
while item2:
alist[i] = item2.pop(0)
i+=1
return alist
if __name__ == '__main__':
alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
print(f'基数排序(Radix Sort)之前原列表的顺序:{alist}')
alist = radix_sort(alist)
print(f'基数排序(Radix Sort)之后的列表的顺序:{alist}')
print(f'基数排序(Radix Sort)之后的正确的顺序:[17, 20, 26, 31, 44, 54, 55, 77, 93]')
大家可以把代码放置到编译器里面,debug运行,看一哈具体的过程,结合动态图片演示理解更好!
4、评判算法
- 最好时间复杂度:O(d(r+n))
- 最坏时间复杂度:O(d(r+n))
- 平均时间复杂度:O(d(r+n))
- 空间复杂度:O(rd+n)
- 算法稳定性:稳定的排序