基数排序
介绍:
排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,前一个键排序的结果可以为后一个键排序所用。基数排序就是这样,先按低位排序,逐次按高位排序,低位排序后元素的顺序在高位也相同时是不会改变的。基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。
思想:
将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。基数排序的方式可以采用 LSD(Least significant digital)或 MSD(Most significant digital),LSD 的排序方式由键值的最右边开始,而 MSD 则相反,由键值的最左边开始。
这里我们按照个位数排序,待排序列为:{50, 30, 0, 100, 11, 2, 123, 543, 187, 49},我们采取LSD方式对待排序列排序,效果如下:
代码:
#!/usr/bin/python
def RadixSort(input_list):
def MaxBit(input_list):
#获得最大数的位数的值
max_data = max(input_list)
bits_num = 0
while max_data:
bits_num += 1
max_data //= 10
return bits_num
def digit(num, d):
#取数num上的第d位数字
p = 1
while d > 1:
d -= 1
p *= 10
return num // p % 10
if len(input_list) == 0:
return []
sorted_list = input_list
length = len(sorted_list)
bucket = [0] * length
for d in range(1, MaxBit(sorted_list) + 1):
count = [0] * 10
for i in range(0, length):
count[digit(sorted_list[i], d)] += 1
for i in range(1, 10):
count[i] += count[i - 1]
for i in range(0, length)[::-1]:
k = digit(sorted_list[i], d)
bucket[count[k] - 1] = sorted_list[i]
count[k] -= 1
for i in range(0, length):
sorted_list[i] = bucket[i]
print("%dth"%d)
print(sorted_list)
return sorted_list
if __name__ == '__main__':
input_list = [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
print('input_list')
print(input_list)
sorted_list = RadixSort(input_list)
print('sorted_list')
print(sorted_list)
结果:
input_list
[50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
1th
[50, 30, 0, 100, 11, 2, 123, 543, 187, 49]
2th
[0, 100, 2, 11, 123, 30, 543, 49, 50, 187]
3th
[0, 2, 11, 30, 49, 50, 100, 123, 187, 543]
sorted_list
[0, 2, 11, 30, 49, 50, 100, 123, 187, 543]
分析:
1.算法性能
其中,d代表数组元素最高为位数,n代表元素个数
2.时间复杂度
这个时间复杂度比较好计算:count * length;其中 count 为数组元素最高位数,length为元素个数;所以时间复杂度:O(n * d)
3.空间复杂度
空间复杂度是使用了两个临时的数组:10 + length;所以空间复杂度:O(n)。
4.算法稳定性
在基数排序过程中,每次都是将当前位数上相同数值的元素统一“装桶”,并不需要交换位置。所以基数排序是稳定的算法。