算法与数据结构(十五) 归并排序(Swift 3.0版)
上篇博客我们主要聊了堆排序的相关内容,本篇博客,我们就来聊一下归并排序的相关内容。归并排序主要用了分治法的思想,在归并排序中,将我们需要排序的数组进行拆分,将其拆分的足够小。当拆分的数组中只有一个元素时,则这个拆分的数组是有序的。然后我们将这些有序的数组进行两两合并,在合并过程中进行比较,合并生成的新的数组仍然是有序的。然后再次将合并的有序数组进行合并,重复这个过程,知道整个数组是有序的。
下方我们先给出两个有序数组合并的示意图以及代码,然后给出归并排序的相关内容。归并排序其实就是拆分+合并。废话少说,开始今天的内容。
一、合并两个有序数组
在本篇博客的第一部分我们先给出合并两个有序数组的示意图以及相关代码,在归并排序时,我们会使用到此部分的内容。下方会给出两个有数数组的合并,并且会给出相应的代码实现。
1.有序数组合并的示意图
因为两个有序数组在合并后的新的数组仍然是有序的,所以我们需要对有序数组中的元素进行比较。每次从两个数组中取出最小的那个元素,然后将两个元素进行比较,将最小的那个元素放入到新的数组中。下方就是有序数组合并的示意图。
首先从两个有序数组中取出最小的值,如下所示。我们将9和10取出后进行比较,将较小的9存入我们新的数组中。
重复上个步骤,如果有一个数组中的元素被取完,将另一个数组中剩余的元素直接追加到我们的新的数组中即可。
2.代码实现
根据上述示意图给出相关的代码实现并不困难,下方就是上述过程的代码实现。下方这个mergeArray()函数,就是将两个有序数组合并成一个新的有序数组的具体代码实现。mergeArray()的两个参数就是即将合并的两个有序数组,而返回值就是合并后新的有序的数组。代码比较简单,在此就不做过多赘述了。
二、归并排序
上述实现完两个有序数组合并成新的有序数组完毕后,接下来就该归并排序出场了。在归并排序过程中,会使用到上述的内容。因为我们将无序数列进行分割后,就会不断调用上述的合并代码,将小的有序的数组合并成较大的有序数组,再次合并,直到我们原始的数组是有序的为止。下方会给出相应的示意图以及归并排序的Swift代码实现。
1.归并排序示意图
下方就是我们归并排序的示意图,稍后的代码实现也是根据下方的示意图来写的。所以对下方示意图的充分理解还是很有必要的。在下方示意图中,从上往下就是我们归并排序的整个过程。我们需要排序的序列为[62, 88, 58, 47, 62, 35, 73, 51, 99, 37, 93]。下方是对每一步的解析:
- 首先我们将需要排序的序列进行拆分,拆分成足够小的数组。也就是拆分的数组中只有一个元素。无序数组拆分的所有数组因为其中只含有一个元素,所以都是有序的。我们就可以对这些有序的小数组进行合并了。
- 将拆分的多个有序数组调用第一部分实现的mergeArray()函数进行两两合并,合并后的新数组仍然是有序的。我们再次对这些合并产生的数组进行两两合并,直到所有被拆分的数组有重新被合并成一个大数组位置。这个重新合并生成的数组就是有序的,也就是归并排序所产生的有序序列。
下方就是拆分+多次合并的详细过程,最终我们得到的就是一个有序序列。如下所示:
2、上述过程的代码实现
根据上述的示意图,我们给出相应的代码实现应该是比较容易的。就是将我们的无序数组进行拆分,然后进行多次合并,最后合并成一个大的有序数组。下方代码就是对上述过程的描述。
- 在下方代码中的第一个框中就是将我们的无序数组进行拆分。被拆分的小的有序的数组存入到tempArray中,便于我们下方遍历进行合并。
- 第二个框就是对tempArray中被拆分的数组进行遍历,在遍历的过程中进行两两合并,将合并的数组再次存入到tempArray中,直到tempArray中只含有一个数组为止。
而tempArray最终的数组就是归并排序的最终结果。下方是整个过程,代码并不复杂。
上述代码的实现在有些数据结构的教程上是使用递归实现的,即使是不使用递归实现也比上述代码要麻烦。
三、测试用例
对上述代码的测试我们仍然会使用到我们之前的测试用例,因为上述排序类仍然遵循我们之前定义的SortType协议。下方就是本篇博客的测试用例,也是所有排序方式的测试用例。这个MergeSort类就是我们归并排序的类。
上述用例的输出结果如下,从输出结果中,我们就能明显的看出拆分和合并的整个过程。如下所示:
本篇博客对堆排序的介绍就先到这儿,下篇博客我们将会介绍“快速排序”的详细内容。本篇博客的相关代码依然会在github上进行分享,下方是github分享地址,如下所示:
github代码分享地址:https://github.com/lizelu/DataStruct-Swift/tree/master/AllKindsOfSort
算法与数据结构(十五) 归并排序(Swift 3.0版)的更多相关文章
- 算法与数据结构(十六) 快速排序(Swift 3.0版)
上篇博客我们主要聊了比较高效的归并排序算法,本篇博客我们就来介绍另一种高效的排序算法:快速排序.快速排序的思想与归并排序类似,都是采用分而治之的方式进行排序的.快速排序的思想主要是取出无序序列中第一个 ...
- 算法与数据结构(十四) 堆排序 (Swift 3.0版)
上篇博客主要讲了冒泡排序.插入排序.希尔排序以及选择排序.本篇博客就来讲一下堆排序(Heap Sort).看到堆排序这个名字我们就应该知道这种排序方式的特点,就是利用堆来讲我们的序列进行排序.&quo ...
- 算法与数据结构(十二) 散列(哈希)表的创建与查找(Swift版)
散列表又称为哈希表(Hash Table), 是为了方便查找而生的数据结构.关于散列的表的解释,我想引用维基百科上的解释,如下所示: 散列表(Hash table,也叫哈希表),是根据键(Key)而直 ...
- 数据结构和算法学习笔记十五:多路查找树(B树)
一.概念 1.多路查找树(multi-way search tree):所谓多路,即是指每个节点中存储的数据可以是多个,每个节点的子节点数也可以多于两个.使用多路查找树的意义在于有效降低树的深度,从而 ...
- 算法与数据结构(十) 二叉排序树的查找、插入与删除(Swift版)
在上一篇博客中,我们主要介绍了四种查找的方法,包括顺序查找.折半查找.插入查找以及Fibonacci查找.上面这几种查找方式都是基于线性表的查找方式,今天博客中我们来介绍一下基于二叉树结构的查找,也就 ...
- C#数据结构与算法系列(十五):排序算法(SortAlgorithm)
1.介绍 排序是将一组数据,以指定的顺序进行排序的过程 2.分类 内部排序法:指将需要处理的所有数据都加载到内部存储器中进行排序 外部排序法:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序
- 算法与数据结构(十七) 基数排序(Swift 3.0版)
前面几篇博客我们已经陆陆续续的为大家介绍了7种排序方式,今天博客的主题依然与排序算法相关.今天这篇博客就来聊聊基数排序,基数排序算法是不稳定的排序算法,在排序数字较小的情况下,基数排序算法的效率还是比 ...
- 浅谈算法和数据结构: 十 平衡查找树之B树
前面讲解了平衡查找树中的2-3树以及其实现红黑树.2-3树种,一个节点最多有2个key,而红黑树则使用染色的方式来标识这两个key. 维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种 ...
- 转 浅谈算法和数据结构: 十 平衡查找树之B树
前面讲解了平衡查找树中的2-3树以及其实现红黑树.2-3树种,一个节点最多有2个key,而红黑树则使用染色的方式来标识这两个key. 维基百科对B树的定义为"在计算机科学中,B树(B-tre ...
随机推荐
- 关于CryptoJS中md5加密以及aes加密的随笔
最近项目中用到了各种加密,其中就包括从没有接触过得aes加密,因此从网上各种查,官方的一种说法: 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学 ...
- 使用Visual Studio 2015 开发ASP.NET MVC 5 项目部署到Mono/Jexus
最新的Mono 4.4已经支持运行asp.net mvc5项目,有的同学听了这句话就兴高采烈的拿起Visual Studio 2015创建了一个mvc 5的项目,然后部署到Mono上,浏览下发现一堆错 ...
- Java 征途:行者的地图
前段时间应因缘梳理了下自己的 Java 知识体系, 成文一篇望能帮到即将走进或正在 Java 世界跋涉的程序员们. 第一张,基础图 大约在 2003 年我开始知道 Java 的(当时还在用 Delph ...
- 第一个shell脚本
打开文本编辑器,新建一个文件,扩展名为sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好. #!/bin/bash echo "Hello World !" &quo ...
- Android学习探索之Java 8 在Android 开发中的应用
前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...
- virtualbox linux虚拟机相关
linux虚拟机设置为静态IP 在virtualbox中安装好linux虚拟机后,如果采用的是NAT方式的话,linux虚拟机默认采用dhcp方式自动上网,而且用的是NetworkManager服务而 ...
- [C#] 简单的 Helper 封装 -- SecurityHelper 安全助手:封装加密算法(MD5、SHA、HMAC、DES、RSA)
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Wen. ...
- [C#][算法] 用菜鸟的思维学习算法 -- 马桶排序、冒泡排序和快速排序
用菜鸟的思维学习算法 -- 马桶排序.冒泡排序和快速排序 [博主]反骨仔 [来源]http://www.cnblogs.com/liqingwen/p/4994261.html 目录 马桶排序(令人 ...
- PHP获取上个月最后一天的一个容易忽略的问题
正常来说,PHP是有一个很方便的函数可以获取上个月时间的 strtotime (PHP 4, PHP 5, PHP 7) strtotime - 将任何英文文本的日期时间描述解析为 Unix 时间戳 ...
- C#泛型详解(转)
初步理解泛型: http://www.cnblogs.com/wilber2013/p/4291435.html 泛型中的类型约束和类型推断 http://www.cnblogs.com/wilber ...