题目
改写MERGE过程,使之不使用哨兵元素,而是一旦L或R中的所有元素都被复制回数组A后,就立即停止,再将另一数组中余下的元素复制回数组A中。
分析
L中所有元素都复制回数组A时,i的值是n1+1,同理,R中的所有元素复制回数组A时,j的值为n2+1,所以在循环中加入这两个判断即可。
伪代码
MERGE(A, p, q, r)
1 n1 <- q-p+1
2 n2 <- r-q
3 for i <- 1 to n1
4 then L[i] = A[p+i-1]
5 for j <- 1 to n2
6 then R[j] = A[j+q]
7 i <- 1
8 j <- 1
9 for k <- p to r
10 do if i == n1+1
11 then A[k] <- R[j]
12 j <- j+1
13 else if j == n2+1
14 then A[k] <- L[i]
15 i <- i+1
16 else if L[i] <= R[i]
17 then A[k] <- L[i]
18 i = i+1
19 else A[k] <- R[j]
20 j <- j+1
1 n1 <- q-p+1
2 n2 <- r-q
3 for i <- 1 to n1
4 then L[i] = A[p+i-1]
5 for j <- 1 to n2
6 then R[j] = A[j+q]
7 i <- 1
8 j <- 1
9 for k <- p to r
10 do if i == n1+1
11 then A[k] <- R[j]
12 j <- j+1
13 else if j == n2+1
14 then A[k] <- L[i]
15 i <- i+1
16 else if L[i] <= R[i]
17 then A[k] <- L[i]
18 i = i+1
19 else A[k] <- R[j]
20 j <- j+1
Python代码实现
def merge(a, p, q, r):
n1 = q-p+1
n2 = r-q
L = []
R = []
for i in range(0, n1):
L.append(a[p+i])
for j in range(0, n2):
R.append(a[j+q+1])
i = 0
j = 0
for k in range(p, r+1):
if i > n1-1:
a[k] = R[j]
j += 1
elif j > n2-1:
a[k] = L[i]
i += 1
elif L[i] <= R[j]:
a[k] = L[i]
i += 1
else:
a[k] = R[j]
j += 1