【发布时间】:2017-01-08 18:08:45
【问题描述】:
我正在研究合并排序中使用递归的控制流程。
我使用的特定算法是:
MergeS(ar, p, r){
1. if p<r{
2. k = floor[(p+r)/2]
3. MergeS(ar, p , k)
4. MergeS(ar, k+1, r) //in the schematic diagram I have written this as mergeS(,,)
5. Merge(ar, p ,k, r)
6. }
7.}
Merge(ar, p, k, r){
8. n1 = k-p+1
9. n2 = r-p
10. let L[1...n1+1] and R[1....n2+1] be new arrays
11. for i=1 to n1
12. L[i] = ar[p+i-1]
13. for j=1 to n2
14. R[j] = ar[k+j]
15. L[n1+1] = Infinity
16. R[n2+1] = Infinity
17. i = 1
18. j = 1
19. for t = p to r
20. if L[i] <= R[j]
21. A[t] = L[i]
22. i = i+1
23. else
24. A[t] = R[j]
25. j = j+1
30. }
MergeS(ar, k+1, r) 与merge(ar, k+1, r) 完全相同。我在后者中使用了小写的m,只是为了在示意图中获得更好的视觉清晰度。
为了便于理解,我举了一个数组的例子——43,32,56,12,4。
递归调用的流程如下图所示,直到第一次调用 Merge 并执行该块内的代码。
---1:MergeS(ar, 0, 5)-----
if(0<5):true ; set k=(0+5)/2
---暂停1:MergeS(ar, 0, 5)-----Call-->2:MergeS(ar, 0, 2) ---------
if(0<2):true ; set k=(0+2)/2
---暂停2:MergeS(ar, 0, 2)-----调用-->3:MergeS(ar, 0, 1) ---------
if(0<1):true ; set k=(0+1)/2
---暂停 3:MergeS(ar, 0, 1)-----Call-->4:MergeS(ar, 0, 0) ---------
if(0<0):false
---简历3:MergeS(ar, 0, 1)-----Call-->5:mergeS(ar, 0+1, 5)强>---------
if(1<5):true ; set k=(1+5)/2
---暂停5:mergeS(ar, 0+1, 5)-----调用-->6:MergeS(ar, 1, 3)强>---------
if(1<3):true ; set k=(1+3)/2
---暂停 6:MergeS(ar, 1, 3)--Call-->7:MergeS(ar, 1, 2) ---------
if(1<2):true ; set k=(1+2)/2
---暂停 7:MergeS(ar, 1, 2)-----Call-->8:MergeS(ar, 1, 1) ---------
if(1<1):false
---简历 7:MergeS(ar, 1, 2)-----Call-->9:mergeS(ar, 1+1, 5)---------
if(2<5):true ; set k=(2+5)/2
---暂停9:mergeS(ar, 2, 5)--------调用-->10:Merge(ar, 2, 3)---------
if(2<3):true ; set k=(2+3)/2
---暂停 10:Merge(ar, 2, 3)-------调用-->11:Merge(ar, 2, 2)强>---------
if(2<2):false
---简历 10:MergeS(ar, 2, 3)-----Call-->12:mergeS(ar, 2+1, 5)强>---------
if(3<5):true ; set k=(3+5)/2
---暂停 12:mergeS(ar, 2+1, 5)--------调用-->13:MergeS(ar, 5, 5 )---------
if(5<5):false
---简历12:mergeS(ar, 2+1, 5)-------调用-->Merge(ar, 3, 4, 5) ---------
n1 = 4-3+1=2
n2 = 5-4=1
for(i = 0 to i=1):
iteration1:
L[0] = ar[3+0-1]= ar[2] //value 56 is assigned to ar[2]
iteration2:
L[1] = ar[3+1-1] = ar[3] //value 12 is assigned to ar[3]
for(j=0 to j=0):
iteration1:
R[0] = ar[4+0] = ar[4] //value 4 is assigned to ar[4]
x = 0;
y = 0;
for(t=0 to t=1):
iteration1:
/* if(L[0]<= R[0]) //56<=4:false */
else
ar[0] = R[0] //4 is assigned to ar[0]
y = y+1
iteration2:
if(L[0]<=R[1]): //56<=infinity
ar[1] = L[0] // 56 is assigned to ar[1]
在上一步之后,我在ar[0] 中得到了一个值4,在ar[2] 中得到了一个值56。我的猜测是这是错误的。
我需要帮助了解我出错的地方以及对此的解释。
【问题讨论】:
-
显示的递归调用流显示从 0 开始的索引,但伪代码显示从 1 开始的索引。使用 p = 起始索引和 r = 结束索引 (1过去数组的最后一个元素)。两个 MergeS 递归调用将是 MergeS(ar, p, k) 和 MergeS(ar, k, r) ...(k 而不是 k+1)。
-
如果我采用 MergeS(ar, k, r) 则中间索引元素将不必要地在每个递归调用中多次复制(当调用除法的右侧部分时)。如果您可以检查我在每次调用中传递的参数并验证它们是否正确?如果不是,我在什么电话中输入了错误的参数。
-
假设 r 是 MergeS(ar, p, r) 中的结束索引,那么整个数组的基于 C 的循环将是 for(i = 0; i
-
好的,明白了。你和我在终止条件上基本不同(我假设
标签: algorithm sorting recursion merge