为什么在Merge-Sort算法中需要在排序之前将数组分成两部分?

时间:2016-03-19 08:02:07

标签: arrays algorithm sorting merge

这可能是一个愚蠢的问题,但我想知道为什么合并排序算法有必要将列表分成两个并合并输出每个分区,然后将所有这些分区合并到一个排序列表中,如此动画所示:

http://www.ee.ryerson.ca/~courses/coe428/sorting/mergesort.html

似乎接近mergesort算法的末尾,当它到达将两个大型数组合并在一起的阶段时,为什么不首先做到这一点呢?我不明白为什么有必要合并输出数组的每个部分,而似乎算法可以将整个列表分成两部分并在第一步中将它们合并在一个排序数组中。

我在这里错过了什么吗?

3 个答案:

答案 0 :(得分:0)

  

我不明白为什么有必要合并排序数组的每个部分,而似乎算法可以将整个列表分成两部分并在第一步中将它们合并在一个排序数组中。

您似乎错过了这样一个事实:只有在合并的部件已经按排序顺序时,合并才有效。如果您只是尝试将输入拆分为两半并合并它们而不对它们进行递归排序,则合并将无法正常工作,并且输出实际上不会被排序。

答案 1 :(得分:0)

合并仅适用于已排序的列表。因此,除非得到一个或两个元素,否则可以通过单独排序或使用交换进行简单排序。然后进行合并,从一个或另一个列表中按顺序获取元素。这就是为什么必须对两个列表进行排序以及为什么对结果进行排序的原因。

答案 2 :(得分:0)

应该注意的是,自下而上合并排序的变体是大多数库中实际使用的变量,例如std :: stable_sort。到达大小为1时,不是递归地将列表和子列表分成两部分,而是自下而上的合并排序跳过不需要的递归,只需将n个元素的列表视为n个列表,每个元素包含1个元素,然后开始合并子列表,增加每次传递的排序运行大小,直到整个列表排序。

在自顶向下或自底向上(非混合)合并排序的任何一种情况下,在生成1的运行大小之前不会发生合并,因为可以认为大小为1的运行被排序。之后,合并大小为1的运行以形成大小为2的运行,然后将这些运行合并以形成大小为4的运行,依此类推,直到生成与原始列表具有相同大小的单个运行。

作为一种变体,混合合并排序可能只会将子列表大小减少到一些小的数量,比如32个元素,然后在开始合并过程之前在32个元素子列表上使用类似插入排序的东西。

关于合并排序的wiki文章有一个简化的自下而上合并排序示例:

http://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation