归并排序从字面上来看,它的大致核心应与归并有关——归并拆分开来,变成归类和合并,归类则是将数组进行有序化,合并则是将两个有序的数组进行合并变成一个有序的数组。
它的特点在于并不是一开始就将整个数组进行归类和调整,而是以一定的间隔数分成多次小的排序,最后再逐渐将小的排序的范围变大,最后变大到整个数组时,已经完全有序。
算法思想和图解
递归法(Top-down)
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
- 重复步骤3直到某一指针到达序列尾
- 将另一序列剩下的所有元素直接复制到合并序列尾
迭代法(Bottom-up)
原理如下(假设序列共有n个元素)
- 将序列每相邻两个数字进行归并操作,形成Ceil(n/2)个序列,排序后每个序列包含两/一个元素
- 若此时序列数不是1个则将上述序列再次归并,形成Ceil(n/4)个序列,每个序列包含四/三个元素
- 重复步骤2,直到所有元素排序完毕,即序列数为1
界定比较的数据个数:一般按照2的倍数增长:两个互相比较、四个互相比较、八个互相比较…下图可以很好地说明这种方法

上图根据颜色的不同进行分组,可以看到先分成两个数据。再分成四个…
C语言代码分析
非递归的归并排序
时间复杂度
O(nlogn)
稳定性
鉴于归并排序会改变前后元素的相对位置,所以:不稳定
分治思想
我们发现快速排序和归并排序都使用了一种分治的思想,这里对其进行简单介绍一下,以便更好地理解归并排序


分治模式在每层递归时都有三个步骤:
1.分解原问题为若干子问题,这些子问题是原问题的规模较小的实例,也就是说实际上子问题也可以看作是一个原问题。
2.解决这些子问题,递归地求解各子问题。然而,若子问题的规模足够小,则直接求解。
3.合并这些子问题的解成原问题的解。
归并排序算法完全遵循分治模式。直观上其操作如下:
- 分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列。
- 解决:使用归并排序递归地排序两个子序列。
- 合并:合并两个已排序的子序列以产生已排序的答案。
所以从这个角度来看实际上分治思想也是基于递归的思想来解决问题的。所以间接地也能帮助我们理解递归的思想。

在计算机科学中,分治法(英语:Divide and conquer)是建基于多项分支递归的一种很重要的算法范型。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。

分治法能解决的问题一般有如下特征:
- 该问题的规模缩小到一定的程度就可以容易地解决。
- 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质,利用该问题分解出的子问题的解可以合并为该问题的解。
- 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
总的来说,分治法也可以被称作一种算法,它是一种基于递归的、“分而治之”的算法思想。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/12902.html