基数排序不用比较每个数的大小而是通过将每个数不同位数上的值放到桶里对应的位置,先按照个位排完,然后按这个排完后的数组的数的十位排,以此类推,最后得到一个有序序列。
排序过程
比如输入一个无序数列:
res = [95, 45, 15, 78, 814, 51, 24, 12]
先求出每个数个位上的数,然后把这个数放到对应的桶的位置上。如上图第一个数是95,个位是5,我们新建一个长度与数列长度相同的桶bucket,将这个数放到第,5个位置上bucket[5]; 第二个是45,个位是5,把数也放到第5个位置上,以此类推。当个位上的数全部都放大桶之后,清空输入的数列,把桶的数列当做新的数列开始按照十位上的数重复上面的操作。
动画过程(来自参考博客)
python 实现
import math
def Radix_Sort(res, radix=10):
# 列表res, 基数radix
# 获取最大的位数
K = int(math.ceil(math.log(max(res), radix))) #最大的整数由几位数组成
for i in range(1, K+1):
# bucket 数组长度为10,存储对应的10个数字
bucket = [[] for c in range(radix)]
for value in res:
x = int(value%(radix**i)/(radix**(i-1))) #计算每个位置上的数值
bucket[x].append(value) #将数放到桶对应的位置
del res[:]
# 把bucket列表中的元素重新放入输入列表作为下一轮的输入
for each in bucket:
res.extend(each)
res = [95, 45, 15, 78, 814, 51, 24, 12]
Radix_Sort(res, 10)
执行过程: https://goo.gl/Qykcnh
效率分析
基数排序的时间复杂度是O(k * n),其中n是排序元素个数,k是数字位数。如上面的代码其实k≈logbNk≈logbN,b是输入序列的最大值。
稳定性
基数排序基于分别排序,分别收集,所以其是稳定的排序算法。
参考:
https://blog.csdn.net/xin_ge_cheng_xu/article/details/79497546
https://blog.csdn.net/lemon_tree12138/article/details/51695211
https://blog.csdn.net/You_are_my_dream/article/details/54789969