算法与数据结构(十七) 基数排序(Swift 3.0版)
前面几篇博客我们已经陆陆续续的为大家介绍了7种排序方式,今天博客的主题依然与排序算法相关。今天这篇博客就来聊聊基数排序,基数排序算法是不稳定的排序算法,在排序数字较小的情况下,基数排序算法的效率还是比较高的。今天就来聊一下基数排序算法的原理以及代码的具体实现。
一、基数排序算法示意图
下方的基数排序算法的实现是利用“桶”来实现的,首先我们创建10个桶,然后按照基数入桶,基数的取值是从数字的低位到高位以此取值。我们还是以[62, 88, 58, 47, 62, 35, 73, 51, 99, 37, 93]这个序列为例,使用基数排序的方式对该序列进行升序排列。
下方截图就是上述序列基数排序的具体过程,在排序之前我们先得创建10个空桶,并进行0-9的编号。这10个空桶会在基数排序的过程中存储我们要排序的数值。下方就是对基数排序步骤的详细介绍:
(1)、以无序序列数值的个数为基数,将无序序列中的值进入到基数对应的桶中。以51为例,如果取个位数为基数的话,51的基数就为1,那么51就进入如编号为1的桶中。以此类推,62在本轮入桶过程中就进入编号为2的桶中。以个位数为基数入桶的结果如下所示。
(2)、个位数为基数入桶完毕后,在安装编号从小到大将桶中的数据以此取出,在存入我们之前的数组中。如下所示。
(3)、在第二步生成的数组的基础上再以十位数为基数入桶。入桶完毕后,再次按照桶的编号顺序将数值取出。
(4)、因为在下方无序的数据中,最大值不超过两位,所以以十位为基数入桶出桶后就已经是有序的了。如果最大值是十万,那么我们一直取基数入桶到十万位为止。也就是排序的数值越大,我们入桶出桶的次数就越多,所以随着位数的增大,排序效率会下降。
二、基数排序算法的代码实现
看完基数排序的原理后,接下来我们就要给出相应的代码实现了。当然本篇博客我们依然使用Swift面向对象语言来给出相应的代码实现。下方代码的实现主要是按照上述示意图的步骤,接下来我们就来循序渐进的来看一下代码的具体实现。
1.创建10个空桶
首先我们需要创建10个空桶,在此我们用一个数组中存放10个数组,这10个数组就是我们相应的桶。而这10个数组所对应的下标就是桶的编号。下方这个createBucket()方法就负责创建10个空桶,并返回。返回结果的类型是Array<Array<Int>>,是一个二维数组。外层数组中存放的就是10个桶,下标是桶的编号。内层数组就是一个桶,负责存放与该桶编号相等的基数对应的数值。具体代码如下所示。
2.计算无序序列中最大的数值
接着我们要实现一个函数用来计算无序序列中最大的数值,取基数入桶出桶的次数以此最大数值的位数为准。比如最大数值为5位,那么我们取基数就从第一位取到第5位,每取一位基数就要按照该基数进行入桶和出桶操作。下方代码就是计算无序数列中最大的那个值,代码还是比较简单的,如下所示:
3、获取数字的长度
上面计算完元素后,我们需要计算该最大值的长度。因为长度的值,就是取基数的次数。下面就是获取数值的长度的函数,其实就是将数字转换成字符串,字符串再转换成字符数组,然后返回字符数组的个数。具体代码如下所示:
4、获取数值中特定位数的值
下方的函数就是获取某数字特定位数的值,你可以通过取余以及求模的方式来获取,以239为例,我想获取十位数值3,那么我们需要将239执行Int((239%100)/10), 通过该操作,我们就可以获取十位上的数值。但是在下方函数中并未采用此方法,而是采用将数字转换成字符串,然后将字符串转换成字符数组,这样我们就可以轻松的取出数字中的任何一位。下方就是具体代码的实现:
5、基数排序的具体代码实现
万事俱备只欠东风,上述做的都是基数排序的准备工作,接下来我们就开始调用上述的方法来实现我们的基数排序的具体代码了。下方就是基数排序的具体代码,如果上述的几个函数搞明白了,那么下方代码并不难理解。先创建桶,获取无序数列中最大的值,然后获取这个最大值的长度。然后就是通过for循环不断的去基数进行入桶和出桶的操作了,如下所示:
三、测试用例
用我RadixSort类遵循了SortType方法,我们依然可以使用之前的测试用例。下方就是我们的测试用例,与之前使用的一直,只不过需要将RadixSort这个类的对象传给我们的测试函数即可,如下所示:
上述测试用例的输出结果如下所示:
本篇博客对堆排序的介绍就先到这儿,下篇博客我们将会介绍“各种排序的动态排序过程”的详细内容。本篇博客的相关代码依然会在github上进行分享,下方是github分享地址,如下所示:
github代码分享地址:https://github.com/lizelu/DataStruct-Swift/tree/master/AllKindsOfSort
算法与数据结构(十七) 基数排序(Swift 3.0版)的更多相关文章
- 算法与数据结构(十六) 快速排序(Swift 3.0版)
上篇博客我们主要聊了比较高效的归并排序算法,本篇博客我们就来介绍另一种高效的排序算法:快速排序.快速排序的思想与归并排序类似,都是采用分而治之的方式进行排序的.快速排序的思想主要是取出无序序列中第一个 ...
- 算法与数据结构(十五) 归并排序(Swift 3.0版)
上篇博客我们主要聊了堆排序的相关内容,本篇博客,我们就来聊一下归并排序的相关内容.归并排序主要用了分治法的思想,在归并排序中,将我们需要排序的数组进行拆分,将其拆分的足够小.当拆分的数组中只有一个元素 ...
- 算法与数据结构(十四) 堆排序 (Swift 3.0版)
上篇博客主要讲了冒泡排序.插入排序.希尔排序以及选择排序.本篇博客就来讲一下堆排序(Heap Sort).看到堆排序这个名字我们就应该知道这种排序方式的特点,就是利用堆来讲我们的序列进行排序.&quo ...
- Swift互用性:与 Cocoa 数据类型共舞(Swift 2.0版)-b
本节内容包括: 字符串(Strings) 数值(Numbers) 集合类(Collection Classes) 错误(Errors) Foundation数据类型(Foundation Data T ...
- Swift互用性: 使用Objective-C特性编写Swift类(Swift 2.0版)-b
本节包括内容: 继承Objective-C的类(Inheriting from Objective-C Classes) 采用协议(Adopting Protocols) 编写构造器和析构器(Writ ...
- Using Swift with Cocoa and Objective-C(Swift 2.0版):开始--基础设置-备
这是一个正在研发的API或技术的概要文件,苹果公司提供这些信息主要是为了帮助你通过苹果产品使用这些技术或者编程接口而做好计划,该信息有可能会在未来发生改变,本文当中提到的软件应该以最终发布的操作系统测 ...
- Swift互用性:与 C的API交互(Swift 2.0版)-b
节包含内容: 基本数据类型(Primitive Types) 枚举(Enumerations) 指针(Pointer) 全局常量(Global Constants) 预处理指令(Preprocesso ...
- Swift互用性:采用Cocoa设计模式(Swift 2.0版)-b
本页包含内容: 委托(Delegation) 错误处理(Error Handling) 键值观察(Key-Value Observing) Target-Action模式(Target-Action) ...
- Swift互用性:与 Objective-C 的 API 交互(Swift 2.0版更新)-备
本页包含内容: 初始化 可失败初始化 访问属性 方法 id 兼容性(id Compatibility) 空值和可选值 扩展(Extensions) 闭包(Closures) 比较对象 Swift 类型 ...
随机推荐
- 从I/O复用谈epoll为什么高效
上一篇文章中,谈了一些网络编程的基本概念.在现实使用中,用的最多的就是I/O复用了,无非就是select,poll,epoll 很多人提到网络就说epoll,认为epoll效率是最高的.单纯的这么认为 ...
- .NetCore MVC中的路由(1)路由配置基础
.NetCore MVC中的路由(1)路由配置基础 0x00 路由在MVC中起到的作用 前段时间一直忙于别的事情,终于搞定了继续学习.NetCore.这次学习的主题是MVC中的路由.路由是所有MVC框 ...
- HTML中上传与读取图片或文件(input file)----在路上(25)
input file相关知识简例 在此介绍的input file相关知识为: 上传照片及文件,其中包括单次上传.批量上传.删除照片.增加照片.读取图片.对上传的图片或文件的判断,比如限制图片的张数.限 ...
- ElasticSearch 5学习(10)——结构化查询(包括新特性)
之前我们所有的查询都属于命令行查询,但是不利于复杂的查询,而且一般在项目开发中不使用命令行查询方式,只有在调试测试时使用简单命令行查询,但是,如果想要善用搜索,我们必须使用请求体查询(request ...
- 博客使用BOS上传图片
1.博客平台的选定 从大学开始做个人主页算起,最开始是使用html,CSSS写简单的页面,后面大学毕业之后接触到了WordPress,就开始用WordPress搭建网站.现在还维护着一个农村网站.ht ...
- 阿里云服务器上配置并使用: PHP + Redis + Mysql 从配置到使用
(原创出处为本博客,http://www.cnblogs.com/linguanh/) 目录: 一,下载 二,解压 三,配置与启动 四,测试 Redis 五,配置 phpRedis 扩展 六,综合测试 ...
- jdb调试scala代码的简单介绍
在linux调试C/C++的代码需要通过gdb,调试java代码呢?那就需要用到jdb工具了.关于jdb的用法在网上大家都可以找到相应的文章,但是对scala进行调试的就比较少了.其实调试的大致流程都 ...
- BPM Domino集成解决方案
一.需求分析 Lotus Notes/Domino是IBM的协同办公平台,在国内有广泛的用户. 但由于推出年头较早.采用文档数据库等特点, 导致其流程集成能力弱.统计分析难.不支持移动办公等问题,很多 ...
- could not initialize proxy - no Session
这是一个精典的问题:因为我们在hibernate里面load一个对象出来时,用到的是代理对象,也就是说当我们在执行load方法时并没有发sql语句,而是返回一个proxy对象.只有当们具体用到哪个ge ...
- Aop动态生成代理类时支持带参数构造函数
一.背景 在某些情况下,我们需要植入AOP代码的类并没有默认构造函数.那么此时动态生成的代理类也需要相同签名的构造函数,并且内部调用原始类的构造函数.自己折腾了1晚上没搞定,现在搞定了发出来供大家一起 ...