【算法】基数排序

2021-06-21 14:03

阅读:513

1、  基数排序原理

基数排序(radix sort)是一种只适用于数字或字母类型的排序方法,它检查数字或字母的每一位,将之分类,按照位数的特定顺序,来将元素排列,比如身份证排序,邮编排序,字符串排序。以数字为例,将所有元素按照个位数字分类,分类好后,将个位数字大小排列组合起来,再按照十位数字分类,再按照数字大小排列组合起来,一直到最大数位为止。

2、  基数排序和其他排序的不同

基数排序不是一种普通的排序算法,它主要适用于邮政编码、社会安全号码或者产品编码等数据的排序。排序关键码可以是整数、实数或者字符串等,但我们必须要知道序列当中,最大关键码所拥有的位数或者说是字符数,以便于确定按位分类的循环次数。

?   序列中的每一个关键码的分类,都基于其某一位数字或者字母;

?   在某一位含相同数字或者字母的关键码,都归为一个分类;

?   分类完成后,按照类别的顺序排列,统一分类的关键码以队列的形式排列,即遵循先进先出的原则。

3、  基数排序实现思想解释

如下图,其中bin0-bin9可以表示10个桶,第一次按照每个元素的个位数字将数字放到对应的桶中,比如10的个位数字是0,就放到bin0这个桶中,37的个位数字是7,就放到bin7这个桶中,以此类推。

 技术分享图片

放完后依次将bin0-bin9桶中的元素取出来,得到下面的列表。

然后再将现有的列表按照十位数的数字放到对应的桶中,比如29放到bin2桶中,10放到bin1桶中,5和8就放到bin0桶中,如下图。

 技术分享图片

然后再依次将bin0-bin9桶中的元素取出来,得到下面的列表

 技术分享图片

这个就是排好序的列表了,以上演示的数字只是到十位数,如果数字是百位数,千位数,依然可以用这个办法,第三次就按照百位数来向桶中放元素,不够百位的都放到bin0中。

4、  基数排序代码

def  randix_sort(array):

    #0表示比对的是个位数

   bucket,digit=[[],[],[],[],[],[],[],[],[],[]],0

    #当bin0桶中的元素个数等于array的长度时,说明所有元素都比对完了

    while len(bucket[0])!=len(array):

        print("bucket[0]:",bucket[0])

        bucket = [[], [], [], [], [], [], [], [], [], []]

        for i in range(len(array)):

            #除以10的digit次方,取整,然后跟10取余

            num=(array[i]//10**digit)%10

            #放到对应的桶中

            bucket[num].append(array[i])

        #将array置空,将每次bucket中的元素放到array中,方便下次while循环判断

        array=[]

        for i in range(len(bucket)):

            array += bucket[i]

        #print (digit,":",array)

        digit += 1

   return array

 

print (randix_sort([5,4,7,2,94,23,7,14,18,10,27,39,74,37,101,1101]))

 

5、  基数排序理解:

(1)  其实第一次排序的时候就把个位数的都排好序了;并且把十位数相同,个位数不同的也排好序了

(2)  第二次排序的时候,比的是十位数,所以这次一位数的数字大小顺序没变;到第二次排序时就把两位数的都排好序了

(3)  当0桶中的长度等于待排序列表的长度,就说明排序结束了

(4)  放入桶中的元素的顺序不能变

(5)  怎么取个位数十位数和百位数,表达式为:(array[i] // 10 ** digit) % 10

 技术分享图片

6、  基数排序的时间复杂度

O(d(n+r))

 技术分享图片

 


评论


亲,登录后才可以留言!