排序原理:
类似于多条件排序(如先按工资高低排序,在按年龄排序,在工资顺序决定的条件下,用年龄大小来决定最后排序),给定所排数,个位当做第一个条件,十位第二个…
首先判断所排序数中最大数有多少位(如max_num = 10000,有5位),其中,输出位数的代码可以好好看一下
从个位的数开始分类,把每一个排序数分到0->10中对应的桶,排好后按桶的顺序输出,还原到列表li中,此时,所有排序数在个位数上是已经排好顺序
再对十位的数进行分桶操作...循环到最大数的位数,输出,所得即排序完成的列表
def radix_sort(li):
max_num = max(li)# 99->2 , 888 ->3 ,10000 ->4
it = 0
while 10 ** it <= max_num:
buckets = [[] for _ in range(10)]
for var in li:
# 987%10 it=0 ;987//10->98 98%10 ->8 it =1;987//100->9 9%10->9 it =2
digit = (var // 10**it)%10
buckets[digit].append(var)
#分桶完成
li.clear()
for buc in buckets:
li.extend(buc)
#把数重新写进列表li中
it += 1
//测试
import random
li = list(range(1000))
random.shuffle(li)
radix_sort(li)
print(li)
——————————————————————————————————
有个问题
发现结果是乱序的
为啥不行?
- 这是由数字的每一位所代表的进制大小优先级决定的,高位的数字在比较大小时具有更高的优先级/重要性。
- 如果从高位开始排,高位排好的顺序在排低位时会被打乱,从而打乱了其所代表数值的顺序。
- 而如果从低位开始排,低位排好的顺序在排高位时被打乱也没关系,因为这时决定整体数值顺序的主要是高位的数字顺序,至于低位,只要保证在高位相同时低位是按序排列这一条件即可,而这个条件只需要在每一位排序时采用稳定的排序算法(如计数排序)即可保证。
如果我非要从高位到低位排序呢?
- 非要从高到低排也可以,但就不能像基数排序一样在排好高位之后直接将所有数字重新按低位排了,而是应该只在高位相同的子数组内部按照低位排序,这也是符合我们平常手动排序时的经验的。
- 这样排的时间复杂度和空间复杂度应该都是和基数排序一样的(本质都是在每一位上用一遍计数排序),稳定性似乎也能得到保证?
- 缺点就是递归算法需要要调用栈,实际用时比较长吧。
部分内容转自「HearOfGold」的原创文章
原文链接:https://blog.csdn.net/qq_41467972/article/details/108172754