前面几篇博客我们已经陆陆续续的为大家介绍了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版)的更多相关文章

  1. 算法与数据结构(十六) 快速排序(Swift 3.0版)

    上篇博客我们主要聊了比较高效的归并排序算法,本篇博客我们就来介绍另一种高效的排序算法:快速排序.快速排序的思想与归并排序类似,都是采用分而治之的方式进行排序的.快速排序的思想主要是取出无序序列中第一个 ...

  2. 算法与数据结构(十五) 归并排序(Swift 3.0版)

    上篇博客我们主要聊了堆排序的相关内容,本篇博客,我们就来聊一下归并排序的相关内容.归并排序主要用了分治法的思想,在归并排序中,将我们需要排序的数组进行拆分,将其拆分的足够小.当拆分的数组中只有一个元素 ...

  3. 算法与数据结构(十四) 堆排序 (Swift 3.0版)

    上篇博客主要讲了冒泡排序.插入排序.希尔排序以及选择排序.本篇博客就来讲一下堆排序(Heap Sort).看到堆排序这个名字我们就应该知道这种排序方式的特点,就是利用堆来讲我们的序列进行排序.&quo ...

  4. Swift互用性:与 Cocoa 数据类型共舞(Swift 2.0版)-b

    本节内容包括: 字符串(Strings) 数值(Numbers) 集合类(Collection Classes) 错误(Errors) Foundation数据类型(Foundation Data T ...

  5. Swift互用性: 使用Objective-C特性编写Swift类(Swift 2.0版)-b

    本节包括内容: 继承Objective-C的类(Inheriting from Objective-C Classes) 采用协议(Adopting Protocols) 编写构造器和析构器(Writ ...

  6. Using Swift with Cocoa and Objective-C(Swift 2.0版):开始--基础设置-备

    这是一个正在研发的API或技术的概要文件,苹果公司提供这些信息主要是为了帮助你通过苹果产品使用这些技术或者编程接口而做好计划,该信息有可能会在未来发生改变,本文当中提到的软件应该以最终发布的操作系统测 ...

  7. Swift互用性:与 C的API交互(Swift 2.0版)-b

    节包含内容: 基本数据类型(Primitive Types) 枚举(Enumerations) 指针(Pointer) 全局常量(Global Constants) 预处理指令(Preprocesso ...

  8. Swift互用性:采用Cocoa设计模式(Swift 2.0版)-b

    本页包含内容: 委托(Delegation) 错误处理(Error Handling) 键值观察(Key-Value Observing) Target-Action模式(Target-Action) ...

  9. Swift互用性:与 Objective-C 的 API 交互(Swift 2.0版更新)-备

    本页包含内容: 初始化 可失败初始化 访问属性 方法 id 兼容性(id Compatibility) 空值和可选值 扩展(Extensions) 闭包(Closures) 比较对象 Swift 类型 ...

随机推荐

  1. Hadoop 中利用 mapreduce 读写 mysql 数据

    Hadoop 中利用 mapreduce 读写 mysql 数据   有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...

  2. boost强分类器的实现

    boost.cpp文件下: bool CvCascadeBoost::train( const CvFeatureEvaluator* _featureEvaluator, int _numSampl ...

  3. 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...

  4. dotNET跨平台相关文档整理

    一直在从事C#开发的相关技术工作,从C# 1.0一路用到现在的C# 6.0, 通常情况下被局限于Windows平台,Mono项目把我们C#程序带到了Windows之外的平台,在工作之余花了很多时间在M ...

  5. Web性能优化:图片优化

    程序员都是懒孩子,想直接看自动优化的点:传送门 我自己的Blog:http://cabbit.me/web-image-optimization/ HTTP Archieve有个统计,图片内容已经占到 ...

  6. AutoFac在项目中的应用

    技能大全:http://www.cnblogs.com/dunitian/p/4822808.html#skill 完整Demo:https://github.com/dunitian/LoTCode ...

  7. JavaScript模仿块级作用域

    avaScript 没有块级作用域的概念.这意味着在块语句中定义的变量,实际上是在包含函数中而非语句中创建的,来看下面的例子: function outputNumbers(count){ for ( ...

  8. vue双向数据绑定原理探究(附demo)

    昨天被导师叫去研究了一下vue的双向数据绑定原理...本来以为原理的东西都非常高深,没想到vue的双向绑定真的很好理解啊...自己动手写了一个. 传送门 双向绑定的思想 双向数据绑定的思想就是数据层与 ...

  9. 前端性能优化的另一种方式——HTTP2.0

    最近在读一本书叫<web性能权威指南>谷歌公司高性能团队核心成员的权威之作. 一直听说HTTP2.0,对此也仅仅是耳闻,没有具体研读过,这次正好有两个篇章,分别讲HTTP1.1和HTTP2 ...

  10. Android—关于自定义对话框的工具类

    开发中有很多地方会用到自定义对话框,为了避免不必要的城府代码,在此总结出一个工具类. 弹出对话框的地方很多,但是都大同小异,不同无非就是提示内容或者图片不同,下面这个类是将提示内容和图片放到了自定义函 ...