合并在合并排序算法中仅调用一次

时间:2014-09-17 14:44:12

标签: algorithm

在这段代码中,第6行返回数组A中最小的左边部分,它不能被进一步破坏(基本情况)&同样的第7行,它将阵列A的右侧部分切割成最小的子阵列。我想问的是第8行中的合并只被称为一次。它如何多次合并所有小子阵列。直到我们得到排序的A。

说我有A [] = {34,567,87,989,0,43,8,233};

第6行将返回分别包含34,567,87,989的小子阵列。第7行返回0,43,8,233 现在第8行中的合并只调用一次这些子数组如何多次。

例如Merge 34,567和0,43然后Merge子阵列包含34,567和87,989等等。

1)Merge-Sort(A,p,r)
2)if p==r 
3)   return 
4)else
5)   q= floor((p+r)/2)
6)   Merge-Sort(A,p,q)
7)   Merge-Sort(A,q+1,r)
8)   Merge(A,p,q,r)

2 个答案:

答案 0 :(得分:1)

  

第8行中的合并仅被调用一次如何多次使用这些子数组?

由于在要排序的子数组具有多个元素的每个级别调用Merge,因此Merge将在算法的各个阶段传递相同子数组的重叠部分"更深"调用级别。

在您的示例中,将像这样调用merge:

Merge(0, 0, 1)             -- Level 3
Merge(1, 1, 2)             -- Level 3
    Merge(0, 1, 2)         -- Level 2
Merge(2, 2, 3)             -- Level 3
Merge(3, 3, 4)             -- Level 3
    Merge(2, 3, 4)         -- Level 2
        Merge(0, 2, 4)     -- Level 1
Merge(4, 4, 5)             -- Level 3
Merge(5, 5, 6)             -- Level 3
    Merge(4, 5, 6)         -- Level 2
Merge(6, 6, 7)             -- Level 3
Merge(7, 7, 8)             -- Level 3
    Merge(6, 7, 8)         -- Level 2
        Merge(4, 6, 8)     -- Level 1
            Merge(0, 4, 8) -- Level 0

我缩进了调用,以便在调用堆栈中显示它们的位置。

您可以看到阵列的每一半都合并了好几次。在最后一行的最后一次合并之前,左子阵列的一半在第7行合并。前半部分的颜色又在第3和第6行合并。最后,合并在第1,2,4行,和5合并"单元阵列"因为它们只有一个元素而自动排序。

答案 1 :(得分:0)

@dasblinkenlight是正确的,但我喜欢将合并排序(和大多数递归)可视化为树。例如,对于输入[4,3,2,1],您将拥有:

1.   [4,3,2,1]    <- initial invocation will call Merge-Sort() twice and Merge() once
2.   /       \    <- we call Merge-Sort for both halves
3. [4,3]   [2,1]  <- each of those nodes will call again Merge-Sort() twice and Merge() once after their respective Merge-Sort() return
4. /   \   /   \  <- for each node we again call Merge-Sort() for both halfs
5. [4] [3] [2] [1] <- base cases, no calls to Merge() or Merge-Sort(), we go back up the tree

正如您所看到的,我们在每个不是叶子的节点上调用Merge(),这意味着我们会2^lg(n) - 1调用Merge()

这就是递归的工作方式,你进入同一个函数,当你回到树上时,你继续从你的案例Merge-Sort(A,p,q)Merge-Sort(A,q+1,r)进行递归调用的地方。