在这段代码中,第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)
答案 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)
进行递归调用的地方。