12.4 基数排序
基数排序(radix sort)是一种只适用于数字或字母类型的排序方法,它检查数字或字母的每一位,将之分类,按照位数的特定顺序,来将元素排列。
12.4.1 算法描述
以数字为例,将所有元素按照个位数字分类,分类好后,将个位数字大小排列组合起来,再按照十位数字分类,再按照数字大小排列组合起来,一直到最大数位为止。
12.4.2 基本的实现
基数排序不是一种普适的排序算法,它主要适用于邮政编码、社会安全号码或者产品编码等数据的排序。排序关键码可以是整数、实数或者字符串等,但我们必须要知道序列当中,最大关键码所拥有的位数或者说是字符数,以便于确定按位分类的循环次数。
- 序列中的每一个关键码的分类,都基于其某一位数字或者字母;
- 在某一位含相同数字或者字母的关键码,都归为一个分类;
- 分类完成后,按照类别的顺序排列,统一分类的关键码以队列的形式排列,即遵循先进先出的原则。
#-*-coding: utf-8-*-
# 基数排序
from llistqueue import Queue
from array import Array
# numDigits是序列中最大关键码所含的位数
def radixSort(intList, numDigits):
# 创建10个队列,用于储存关键码
binArray = Array(10)
for k in range(10):
binArray[k] = Queue()
# 从个位开始
column = 1
for d in range(numDigits):
for key in intList:
digit = (key / column) % 10 # 得出关键码的某一位数字
binArray[digit].enqueue(key) # 根据数字结果归类
i = 0
for bin in binArray:
while not bin.isEmpty():
intList[i] = bin.dequeue()
i += 1
column *= 10
12.4.3 效率分析
假设序列含有n个关键码,最大的关键码含有d个组成部分,每一个组成部分的取值范围为0,1, .., k-1。由于是使用链表实现的队列,入队和出队的时间复杂度都是O(1)。需要创建k个队列,需要O(k)的时间复杂度。
之后将n个关键码归类,则需要O(n)的时间复杂度,其后的排列也同样需要O(n)的时间复杂度。而这一过程重复执行d次,则总的时间复杂度为O(k+dn)。一般来说,k和d在序列给定之后,都是确定的。所以基数排序的时间复杂度是O(n)。