【写在前面】

参考文章:

https://blog.csdn.net/nrsc272420199/article/details/82691596【给出的示例图,简单易懂,但是对于没一轮循环没有讲解的很清楚】

https://www.cnblogs.com/sfencs-hcy/p/10616446.html【代码实现+思路,值得借鉴】

【正文部分】

  网上有很多关于基数排序的讲解,不过基于每个人的理解力不同,所以理解起来难易程度也有所不同。大家给出的博客、见解很多,不过我找了好久要么就是程序实现的思路,晦涩难懂,要么就是图示复杂难看(没有贬义,不是丑,是不容易看懂的意思),找了好久找到上面推荐的两篇博客,结合两个博主的例子写了这篇博客。好了,下面开始正式的讲解。

  基数排序的原理就是按照将每个元素的从低到高的顺序依次取出各位上的元素,然后每次按照取出的元素进行归类和重整。直到所有的位数都排完。简单的将就是先拆分后整合。借鉴文章1给出的例子,原始数组如下所示:

  第一趟排序,先取出各个元素的个位数字,并进行分组如下:

 
  然后按照每组中的数字添加的顺序对数据进行整合,先进先出,得到新的数组如下,第一趟排序后完成的工作为将数组按照个位数由小到大的顺序进行了排序。

  第二趟,对第一趟的结果按照十位数进行分组,结果如下:

  同样的方法,将分组后的数组按照添加的顺序分别取出,得到新的数组如下:

  第二趟排序后,数组按照十位数由小到大进行了排序,同时由于个位数已经进行了排序,因此将分组后的数组添加顺序取出时,十位数相同的较小的会排在前面,如31和38,43和49

  第三趟,对第二趟的结果按照百位数进行分组,结果如下:

  然后将分组后的数组按照索引的大小分别取出,得到新的数组如下:

  第三趟排序后完成的工作是将数组按照百位数由小到大进行了排序,同时由于个位数和十位数都已经进行了排序,所以较小的数会排在前面,这样就完成了整个数组的排序.

  由上面的过程可以知道如果最大数有n位,则需要n次(按照索引分组+按照索引大小取出数据)循环。所以程序中需要先找出最大数字和最大数字的位数。

  具体实现:

def radix_sort(s):
"""基数排序"""
i = 0 # 记录当前正在排拿一位,最低位为1
max_num = max(s) # 最大值
j = len(str(max_num)) # 记录最大值的位数
while i < j:
bucket_list =[[] for _ in range(10)] #初始化桶数组
for x in s:
bucket_list[int(x / (10**i)) % 10].append(x) # 找到位置放入桶数组
print(bucket_list)
s.clear()
for x in bucket_list: # 放回原序列
for y in x:
s.append(y)
i += 1 if __name__ == '__main__':
a = [334,5,67,345,7,345345,99,4,23,78,45,1,3453,23424]
radix_sort(a)
print(a)

输出结果:

[[], [1], [], [23, 3453], [334, 4, 23424], [5, 345, 345345, 45], [], [67, 7], [78], [99]]
[[1, 4, 5, 7], [], [23, 23424], [334], [345, 345345, 45], [3453], [67], [78], [], [99]]
[[1, 4, 5, 7, 23, 45, 67, 78, 99], [], [], [334, 345, 345345], [23424, 3453], [], [], [], [], []]
[[1, 4, 5, 7, 23, 45, 67, 78, 99, 334, 345], [], [], [23424, 3453], [], [345345], [], [], [], []]
[[1, 4, 5, 7, 23, 45, 67, 78, 99, 334, 345, 3453], [], [23424], [], [345345], [], [], [], [], []]
[[1, 4, 5, 7, 23, 45, 67, 78, 99, 334, 345, 3453, 23424], [], [], [345345], [], [], [], [], [], []]
[1, 4, 5, 7, 23, 45, 67, 78, 99, 334, 345, 3453, 23424, 345345]

  备注:这里贴出文章2中给出的参考代码,这里有一点原博主做的很好,在每一次循环的时候给了一个print函数,可以方便的看出每一轮循环中桶中的数据分布情况。

  原博主在求最大值和最大值的位数的时候用了库函数来实现,方法很好,代码看起来很简洁,不过为了更易懂,或者有时候如果有限制不让用库函数的时候,直接给出一个自定义函数求取参数,另外对响应的代码作出了注释,代码如下所示:

def radix_sort(s):
"""基数排序代码实现"""
maxNum = s[0] # 求取的最大值
for x in s:
if maxNum < x:
maxNum = x
times = 0 # 循环实现的次数
while maxNum > 0:
maxNum = maxNum//10
times = times+1 i = 0 # 记录当前正在排拿一位,最低位为0
while i < times:
bucket_list = [[] for _ in range(10)] # 初始化桶数组为十个空列表
for each in s:
bucket_list[(each // (10**i)) % 10].append(each) # 根据当前所求的位的数值大小,找到对应的位置放入桶数组
s.clear()
for x in bucket_list: # for的嵌套,从桶中取出元素放回原序列
for y in x:
s.append(y)
i += 1 if __name__ == '__main__':
a = [334,5,67,345,7,345345,99,4,23,78,45,1,3453,234]
radix_sort(a)
print(a)

  显然易见,没有了库函数的加持,代码显得很臃肿。。。。

【写在最后】

  该文章是参考上面两个博主的博客写的,也加上了自己的看法和理解,如果有没讲到位的地方,可以去原博客查看。

  博主支持原创,也尊重原创,如有侵权,联系博主删帖,转发注明出处

八大排序算法之基数排序(python实现)的更多相关文章

  1. 八大排序算法的 Python 实现

    转载: 八大排序算法的 Python 实现 本文用Python实现了插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个 ...

  2. Python实现八大排序算法(转载)+ 桶排序(原创)

    插入排序 核心思想 代码实现 希尔排序 核心思想 代码实现 冒泡排序 核心思想 代码实现 快速排序 核心思想 代码实现 直接选择排序 核心思想 代码实现 堆排序 核心思想 代码实现 归并排序 核心思想 ...

  3. Python - 八大排序算法

    1.序言 本文使用Python实现了一些常用的排序方法.文章结构如下: 1.直接插入排序 2.希尔排序 3.冒泡排序 4.快速排序 5.简单选择排序 6.堆排序 7.归并排序 8.基数排序 上述所有的 ...

  4. 【Python】八大排序算法的比较

    排序是数据处理比较核心的操作,八大排序算法分别是:直接插入排序.希尔排序.简单选择排序.堆排序.冒泡排序.快速排序.归并排序.基数排序 以下是排序图解: 直接插入排序 思想 直接插入排序是一种最简单的 ...

  5. 八大排序算法总结与java实现(转)

    八大排序算法总结与Java实现 原文链接: 八大排序算法总结与java实现 - iTimeTraveler 概述 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 ...

  6. [Data Structure & Algorithm] 八大排序算法

    排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.我们这里说的八大排序算法均为内部排序. 下图为排序 ...

  7. 八大排序算法Java实现

    本文对常见的排序算法进行了总结. 常见排序算法如下: 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 它们都属于内部排序,也就是只考虑数据量较小仅需要使用内存的排 ...

  8. 八大排序算法详解(动图演示 思路分析 实例代码java 复杂度分析 适用场景)

    一.分类 1.内部排序和外部排序 内部排序:待排序记录存放在计算机随机存储器中(说简单点,就是内存)进行的排序过程. 外部排序:待排序记录的数量很大,以致于内存不能一次容纳全部记录,所以在排序过程中需 ...

  9. Java八大排序算法

    Java八大排序算法: package sort; import java.util.ArrayList; import java.util.Arrays; import java.util.List ...

随机推荐

  1. Centos8.3安装broadcom(博通)BCM43142无线网卡驱动,Centos8没有wifi选项(No wifi adapter found centos)解决办法

    参考:杆菌大祭司> https://www.jianshu.com/p/3cb41b7b8fec 第一步:查看网卡型号,确认无线网卡型号为BCMXXX lspci | grep Network ...

  2. Linux内核学习之2号进程kthreadd

    Author       : Toney Email         : vip_13031075266@163.com Date          : 2020.12.04 Copyright : ...

  3. HCNP Routing&Switching之IS-IS报文结构和类型

    前文我们了解了IS-IS动态路由协议基础相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15249328.html:今天我们来聊一聊IS-IS动态路由协 ...

  4. ajax获取图片

    <img id="contents2_img" alt="" src="images/hope.png" style="wi ...

  5. vs code使用git---http方式

    1.从git上复制http路径 2.在vs code的工作区新建文件夹 3.选择添加远程储存库 4.输入复制的git路径然后命名远程储存库名称   5.选择从所有远程储存库中拉取分支 6.选择分支,切 ...

  6. python模块--datetime

    datatime.date类 构造器 返回值类型 说明 (year, month, day) date   类方法/属性     .max date datetime.date(9999, 12, 3 ...

  7. 部署MySQL主主复制管理器

    一.概念 MMM(Master-Master replication manager for MvSQL,MySQL主主复制管理器)是一套支持双主故障切换和双主日常管理的脚本程序.MMM 使用 Per ...

  8. jQuery-01

    day01 - jQuery 学习目标: 能够说出什么是 jQuery 能够说出 jQuery 的优点 能够简单使用 jQuery 能够说出 DOM 对象和 jQuery 对象的区别 能够写出常用的 ...

  9. 【转】Linux 查看端口占用情况

    Linux 查看端口占用情况可以使用 lsof 和 netstat 命令. lsof lsof(list open files)是一个列出当前系统打开文件的工具. lsof 查看端口占用语法格式: l ...

  10. Shell系列(37)- while和until循环

    while循环 只要条件判断式成立则进行循环,并执行循环程序:一旦循环条件不成立,则终止循环 格式 while [ 条件判断式 ] do 程序 done 例子 需求:计算工具,1+2+--100的和 ...