【初探】 归并排序


归并排序介绍


● 将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

●   归并排序(MERGE-SORT): 是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案”修补”在一起,即分而治之)。

● 归并排序其实要做两件事:

 (1)“分解”——将序列每次折半划分。

 (2)“合并”——将划分后的序列段两两合并后排序。

归并排序(Merge Sort): 就是利用归并思想对数列进行排序。根据具体的实现,归并排序包括”从上往下”和”从下往上”2种方式。

从下往上的归并排序(自顶向上归并排序):

(1)将待排序的数列分成若干个长度为1的子数列,

(2)然后将这些数列两两合并;得到若干个长度为2的有序数列

(3)再将这些数列两两合并;得到若干个长度为4的有序数列,

(4)再将它们两两合并;得到若干个长度为8的有序数列,

(5)以此类推 ,直到,归并的长度大于整个数组的长度,此时整个数组有序。需要注意的是数组按照归并长度划分,最后一个子数组可能不满足长度要求,这个情况需要特殊处理。自顶向下的归并排序算法一般用递归来实现,而自底向上可以用循环来实现。


从上往下的归并排序(自顶向下):它与”从下往上”在排序上是反方向的。它基本包括3步:

① 分解 – 将当前区间一分为二,即求分裂点 mid = (low + high)/2;

② 求解 – 递归地对两个子区间a[low…mid] 和 a[mid+1…high]进行归并排序。递归的终结条件是子区间长度为1。

③ 合并 – 将已排序的两个子区间a[low…mid]和 a[mid+1…high]归并为一个有序的区间a[low…high]。

 自顶向下的排序算法就是把数组元素不断的二分,直到子数组的元素个数为一个,因为这个时候子数组必

定是已有序的,然后将两个有序的序列合并成一个新的有序的序列,

两个新的有序序列又可以合并成另一个新的有序序列,以此类推,直到合并成一个有序的数组。

这里写图片描述


下面的图片很清晰的反映了”从下往上”(自顶向上)和”从上往下”(自顶向下)的归并排序的区别。

这里写图片描述


从上往下的归并排序(自顶向下)采用了递归的方式实现。它的原理非常简单,如下图:

这里写图片描述

通过”从上往下的归并排序”来对数组{80,30,60,40,20,10,50,70}进行排序时:

      1. 将数组{80,30,60,40,20,10,50,70}看作由两个有序的子数组{80,30,60,40}和{20,10,50,70}组成。
      对两个有序子树组进行排序即可。
  1. 将子数组{80,30,60,40}看作由两个有序的子数组{80,30}和{60,40}组成。
    将子数组{20,10,50,70}看作由两个有序的子数组{20,10}和{50,70}组成。

    3. 将子数组{80,30}看作由两个有序的子数组{80}和{30}组成。
       将子数组{60,40}看作由两个有序的子数组{60}和{40}组成。
       将子数组{20,10}看作由两个有序的子数组{20}和{10}组成。
       将子数组{50,70}看作由两个有序的子数组{50}和{70}组成。
    

从下往上的归并排序(自顶向上)的思想正好与”从上往下的归并排序”相反。如下图:

这里写图片描述

通过”从下往上的归并排序”来对数组{80,30,60,40,20,10,50,70}进行排序时:

1. 将数组{80,30,60,40,20,10,50,70}看作由8个有序的子数组{80},{30},{60},{40},{20},{10},{50}和{70}组成。

2. 将这8个有序的子数列两两合并。得到4个有序的子树列{30,80},{40,60},{10,20}和{50,70}。

3. 将这4个有序的子数列两两合并。得到2个有序的子树列{30,40,60,80}和{10,20,50,70}。

4. 将这2个有序的子数列两两合并。得到1个有序的子树列{10,20,30,40,50,60,70,80}。

这里写图片描述

可以看到这种结构很像一棵完全二叉树,分阶段可以理解为就是递归拆分子序列的过程,递归深度为这里写图片描述


合并相邻有序子序列


  再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤。

这里写图片描述

这里写图片描述


归并排序算法的性能


这里写图片描述

假设被排序的数列中有N个数。遍历一趟的时间复杂度是O(N),需要遍历多少次呢?

归并排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的可以得出它的时间复杂度是 O(n*log2n)。


归并排序稳定性


归并排序是稳定的算法,它满足稳定算法的定义。

算法稳定性 – 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!


空间复杂度


 由前面的算法说明可知,算法处理过程中,需要一个大小为n的临时存储空间用以保存合并序列。

归并排序和堆排序、快速排序的比较


若从空间复杂度来考虑:首选堆排序,其次是快速排序,最后是归并排序。

若从稳定性来考虑,应选取归并排序,因为堆排序和快速排序都是不稳定的。

若从平均情况下的排序速度考虑,应该选择快速排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值