八大排序算法之基数排序
设计思想
它是根据关键字中各位的值,通过对排序的N个元素进行若干趟“分配”与“收集”来实现排序的。它不要比较关键字的大小。
假设:R {50, 123, 543, 187, 49, 30, 0, 2, 11, 100}
任何一个阿拉伯数,它的各个位数上的基数都是以0~9来表示的。所以我们不妨把0~9视为10个桶。 我们先根据序列的个位数的数字来进行分类,将其分到指定的桶中。例如:R[0] = 50,个位数上是0,将这个数存入编号为0的桶中。
分类后,我们在从各个桶中,将这些数按照从编号0到编号9的顺序依次将所有数取出来。这时,得到的序列就是个位数上呈递增趋势的序列。 按照个位数排序: {50, 30, 0, 100, 11, 2, 123, 543, 187, 49}。接下来,可以对十位数、百位数也按照这种方法进行排序,最后就能得到排序完成的序列。
代码实现
import math def get_number(num): import random lst = [] i = 0 while i < num: lst.append(random.randint(0,100)) i += 1 return lst def radixsort(lst,radix=10): k = int(math.ceil(math.log(max(lst),radix))) bucket = [[] for i in range(radix)] for i in range(1,k+1): for j in lst: bucket[j//radix**(i-1) % (radix**i)].append(j) del lst[:] for z in bucket: lst += z del z[:] return lst a = get_number(10) print("排序之前:",a) b = radixsort(a) print("排序之后:",b) ########输出结果########### 排序之前: [2, 4, 26, 46, 90, 16, 80, 36, 37, 72] 排序之后: [2, 4, 16, 26, 36, 37, 46, 72, 80, 90]
性能分析
时间复杂度:通过上文可知,假设在基数排序中,r为基数,d为位数。则基数排序的时间复杂度为O(d(n+r))。我们可以看出,基数排序的效率和初始序列是否有序没有关联。
空间复杂度:在基数排序过程中,对于任何位数上的基数进行“装桶”操作时,都需要n+r个临时空间。
算法稳定:在基数排序过程中,每次都是将当前位数上相同数值的元素统一“装桶”,并不需要交换位置。所以基数排序是稳定的算法。