排序 —— 合并排序

与很多有用的算法类似,合并排序基于这样一个技巧:将 2 个大小为 N/2 的已排序序列合并为一个 N 元素已排序序列仅需要 N 次操作。这个方法叫做合并。

我们用个简单的例子来看看这是什么意思: 
这里写图片描述

通过此图你可以看到,在 2 个 4元素序列里你只需要迭代一次,就能构建最终的8元素已排序序列,因为两个4元素序列已经排好序了:

1) 在两个序列中,比较当前元素(当前=头一次出现的第一个) 
2) 然后取出最小的元素放进8元素序列中 
3) 找到(两个)序列的下一个元素,(比较后)取出最小的 
重复1、2、3步骤,直到其中一个序列中的最后一个元素 
然后取出另一个序列剩余的元素放入8元素序列中。 
这个方法之所以有效,是因为两个4元素序列都已经排好序,你不需要再『回到』序列中查找比较。

【注:合并排序详细原理,其中一个动图(原图较长,我做了删减)清晰的演示了上述合并排序的过程,而原文的叙述似乎没有这么清晰,不动戳大。】 
这里写图片描述 
 

 

 

合并排序是把问题拆分为小问题,通过解决小问题来解决最初的问题(注:这种算法叫分治法,即『分而治之、各个击破』)。如果你不懂,不用担心,我第一次接触时也不懂。如果能帮助你理解的话,我认为这个算法是个两步算法:

  • 拆分阶段,将序列分为更小的序列
  • 排序阶段,把小的序列合在一起(使用合并算法)来构成更大的序列

拆分阶段

这里写图片描述 
在拆分阶段过程中,使用3个步骤将序列分为一元序列。步骤数量的值是 log(N) (因为 N=8, log(N)=3)。【译者注:底数为2,下文有说明】

我怎么知道这个的?

我是天才!一句话:数学。道理是每一步都把原序列的长度除以2,步骤数就是你能把原序列长度除以2的次数。这正好是对数的定义(在底数为2时)。

排序阶段

这里写图片描述 
在排序阶段,你从一元序列开始。在每一个步骤中,你应用多次合并操作,成本一共是 N=8 次运算。

第一步,4 次合并,每次成本是 2 次运算。 
第二步,2 次合并,每次成本是 4 次运算。 
第三步,1 次合并,成本是 8 次运算。 
因为有 log(N) 个步骤,整体成本是 N*log(N) 次运算。

【注:这个完整的动图演示了拆分和排序的全过程,不动戳大。】 
这里写图片描述

合并排序的强大之处

为什么这个算法如此强大?

因为:

你可以更改算法,以便于节省内存空间,方法是不创建新的序列而是直接修改输入序列。 
注:这种算法叫『原地算法』(in-place algorithm)

你可以更改算法,以便于同时使用磁盘空间和少量内存而避免巨量磁盘 I/O。方法是只向内存中加载当前处理的部分。在仅仅100MB的内存缓冲区内排序一个几个GB的表时,这是个很重要的技巧。 
注:这种算法叫『外部排序』(external sorting)。

你可以更改算法,以便于在 多处理器/多线程/多服务器 上运行。 
比如,分布式合并排序是Hadoop(那个著名的大数据框架)的关键组件之一。

这个算法可以点石成金(事实如此!) 
这个排序算法在大多数(如果不是全部的话)数据库中使用,但是它并不是唯一算法。如果你想多了解一些,你可以看看 这篇论文,探讨的是数据库中常用排序算法的优势和劣势。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值