python之基数排序的实现


Posted in Python onJuly 26, 2021

算法思想

        插入\交换\选择\归并类的排序算法都需要通过比较关键字的大小来完成排序.因为存在两两比较所以这一类的排序方法在最好情况下能达到的复杂度是O(n*logn),如快速排序\堆排序\归并排序.在一般情况下和最坏情况下复杂度更是达到O(n**2).

        为了降低复杂度,就有牛人想出了分配收集排序方法,稍后分析它的时间复杂度能到达O(n),

而基数排序就是一种典型的搜集分配收集排序方法.基数排序时一种借助于多关键字排序的思想对单关键字排序的方法.其基本思想是通过对排序记录进行若干趟(有几个关键字就几趟)"分配"与"收集"来实现排序.

        如:

       1. 对整数排序,建立编号0-9(10进制的基数)10个桶,用于装对应位为编号的记录.先将待排序序列分配按'个位'数字分配到10各桶中,然后将桶按从小到大的顺序串接起来.

        2.将上一步的结果再按'十位''数字分配到10各桶中,然后将桶按从小到大的顺序串接起来.

        3. 将上一步的结果再按'百位''数字分配到10各桶中,然后将桶按从小到大的顺序串接起来.

        4.如果还有千位\万位.重复以上步骤,直到完成最高位的分配与收集,排序结束.

动图示例:(转自菜鸟教程:1.10 基数排序 | 菜鸟教程 (runoob.com))

python之基数排序的实现 

算法实现

1.本实现借助队列的数据结构,所以先来定义一个队列

# Bradley N. Miller, David L. Ranum
# Introduction to Data Structures and Algorithms in Python
# Copyright 2005
# 
#queue.py
 
class Queue:
    def __init__(self):
        self.items = []
 
    def isEmpty(self):
        return self.items == []
 
    def enqueue(self, item):
        self.items.insert(0,item)
 
    def dequeue(self):
        return self.items.pop()
 
    def size(self):
        return len(self.items)

2.处理输入数据

将一个列表作为输入,将每一个记录处理为具有相同位数的字符串(用字符串类型时为了方便处理)

def inDataProcess(lis):
    max_lengh = max([len(lis[i]) for i in range(len(lis))])  # 查询记录中最长的字符串
    return [x.zfill(max_lengh) for x in lis]  # 将每一个记录都通过添加前导0的方式转化为一样的长度

3.基数排序主函数

def radixSort(seq:list):
    source_data = inDataProcess(seq)  # 输入处理
    res = []  # 用于保存结果列表
    big_queue = Queue()  # 用于转化的队列
    for ele in source_data:
        big_queue.enqueue(ele)
 
    for i in range(len(source_data[0])-1,-1,-1):
        buckets = []  # 用于保存每一趟的10各基数桶
        for num  in range(10):  # 建立10个基数桶
            bucket = Queue()
            buckets.append(bucket)
        # 在基数桶中插入数据
        while not big_queue.isEmpty():
            currentEle = big_queue.dequeue()  # 大队列中出队一个元素
            index = int(currentEle[i])  # 根据元素对应位上的值添加进对应的基数桶中
            buckets[index].enqueue(currentEle)
 
        # 把基数桶串联起来
        new_big_queue = Queue()
        for bucket in buckets:
            while not bucket.isEmpty():
                out = bucket.dequeue()
                new_big_queue.enqueue(out)
                # print(new_big_queue.size())
        # 修改big_queue
        big_queue = new_big_queue
    # 将大队列中的元素保存到结果列表中
    while not big_queue.isEmpty():
        res.append(big_queue.dequeue().lstrip('0'))  # 利用lstrip('0')去掉前导0
    return res

4.测试及结果

if __name__ == '__main__':
 
    lis = [20,101,39,431,58,600,8,4,999,634,157,199,208,138,389,691,400,932,856,843,401,923]
    lis = [str(i) for i in lis]
    print(radixSort(lis))
    ''' 结果>>>['4', '8', '20', '39', '58', '101', '138', '157', '199', '208', '389', '400', '401', '431', '600', '634', '691',
    '843', '856', '923', '932', '999']'''

算法分析

1)时间复杂度
对于n个记录(假设每个记录含d个关键字,每个关键字的取值范围为rd个值)进行链式基数排序时,每一趟分配的时间复杂度为O(n),每一趟收集的时间复杂度为O(rd),整个排序需进行d趟分配和收集,所以时间复杂度为O(d(n+rd))。
(2)空间复杂度
所需辅助空间为2rd个队列指针,另外由于需用链表做存储结构,则相对于其他以顺序结构存储记录的排序方法而言,还增加了n个指针域的空间,所以空间复杂度为O(n+rd)。

算法的特征

(1)是稳定排序。
(2)可用于链式结构,也可用于顺序结构。
(3)时间复杂度可以突破基于关键字比较一类方法的下界O(nlog2n),达到O(n)。
(4)基数排序使用条件有严格的要求:需要知道各级关键字的主次关系和各级关键字的取值范围。


ref: 

1.严蔚敏等<<数据结构C语言版(第二版)>>

2.Bradley N. Miller, David L. Ranum <<Introduction to Data Structures and Algorithms in Python>>

到此这篇关于python之基数排序的实现的文章就介绍到这了,更多相关python之基数排序内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python3实现生成随机密码的方法
Aug 23 Python
Python使用metaclass实现Singleton模式的方法
May 05 Python
shell命令行,一键创建 python 模板文件脚本方法
Mar 20 Python
Python Json模块中dumps、loads、dump、load函数介绍
May 15 Python
python处理数据,存进hive表的方法
Jul 04 Python
python+opencv+caffe+摄像头做目标检测的实例代码
Aug 03 Python
Python3字符串encode与decode的讲解
Apr 02 Python
详解python3安装pillow后报错没有pillow模块以及没有PIL模块问题解决
Apr 17 Python
python+openCV调用摄像头拍摄和处理图片的实现
Aug 06 Python
用OpenCV进行年龄和性别检测的实现示例
Jan 29 Python
python制作图形界面的2048游戏, 基于tkinter
Apr 06 Python
python使用pywinauto驱动微信客户端实现公众号爬虫
May 19 Python
python之PySide2安装使用及QT Designer UI设计案例教程
python代码实现备忘录案例讲解
Jul 26 #Python
python之django路由和视图案例教程
Jul 26 #Python
OpenCV图像变换之傅里叶变换的一些应用
Python类方法总结讲解
pandas数值排序的实现实例
Jul 25 #Python
python非标准时间的转换
Jul 25 #Python
You might like
php中switch与ifelse的效率区别及适用情况分析
2015/02/12 PHP
php在数据库抽象层简单使用PDO的方法
2015/11/03 PHP
功能强大的PHP POST提交数据类
2016/07/15 PHP
Python中使用django form表单验证的方法
2017/01/16 PHP
PHP实现活动人选抽奖功能
2017/04/19 PHP
Yii2框架中日志的使用方法分析
2017/05/22 PHP
详解php实现页面静态化原理
2017/06/21 PHP
js 复制或插入Html的实现方法小结
2010/05/19 Javascript
CSS和JS标签style属性对照表(方便js开发的朋友)
2010/11/11 Javascript
15条JavaScript最佳实践小结
2013/08/09 Javascript
js隐式全局变量造成的bug示例代码
2014/04/22 Javascript
手机号码,密码正则验证
2014/09/04 Javascript
jQuery实现长按按钮触发事件的方法
2015/02/02 Javascript
jQuery判断元素上是否绑定了指定事件的方法
2015/03/17 Javascript
Jquery实现鼠标移动放大图片功能实例
2015/03/25 Javascript
jquery图片轮播特效代码分享
2020/04/20 Javascript
jQuery控制div实现随滚动条滚动效果
2016/06/07 Javascript
Google 爬虫如何抓取 JavaScript 的内容
2017/04/07 Javascript
BootStrap导航栏问题记录
2017/07/31 Javascript
微信小程序 rich-text的使用方法
2017/08/04 Javascript
JS跳转手机站url的若干注意事项
2017/10/18 Javascript
vue实现公告栏文字上下滚动效果的示例代码
2020/06/16 Javascript
python33 urllib2使用方法细节讲解
2013/12/03 Python
python 3.6.4 安装配置方法图文教程
2018/09/18 Python
Django ORM 聚合查询和分组查询实现详解
2019/08/09 Python
python2使用bs4爬取腾讯社招过程解析
2019/08/14 Python
Python 爬取必应壁纸的实例讲解
2020/02/24 Python
python3 简单实现组合设计模式
2020/07/02 Python
python文件排序的方法总结
2020/09/13 Python
python 多进程和协程配合使用写入数据
2020/10/30 Python
10个顶级Python实用库推荐
2021/03/04 Python
捷克原创男装和女装购物网站:Bolf.cz
2018/04/28 全球购物
英国计算机商店:Technextday
2019/12/28 全球购物
语文教学随笔感言
2014/02/18 职场文书
群众路线教育党课主持词
2014/04/01 职场文书
2016国庆节活动宣传语
2015/11/25 职场文书