如何通过推理循环不变量的状态来证明合并排序的正确性?我唯一可以想象的是,在合并步骤中,子组合(不变量)在组合时保持它们的状态,即它们是在每个合并步骤再次排序。但我不知道我是否正确进行。我对循环不变量和东西没有太多了解。可以在这一个上启发我吗?解释每个阶段会发生什么
a)初始化 b)维护 c)终止
非常有责任!
答案 0 :(得分:3)
合并排序的伪代码
MERGE-SORT(A,p,r)
1 if p < r
2 then q <-- [(p + r) / 2]
3 MERGE-SORT(A, p, q)
4 MERGE-SORT(A, q + 1, r)
5 MERGE-SORT(A, p, q, r)
MERGE-SORT(A,p,q,r)
1 n1 <-- q - p + 1
2 n2 <-- r - q
3 create arrays L[1 ... n1 + 1] and R[1 ... n2 + 1]
4 for i <-- 1 to n1
5 do L[i] <-- A[p + i - 1]
6 for j <-- 1 to n2
7 do R[j] <-- A[q + j]
8 L[n1 + 1] <-- infinite
9 R[n2 + 1] <-- infinite
10 i <-- 1
11 j <-- 1
12 for k <-- p to r
13 do if L[i] <= R[j]
14 then A[k] <-- L[i]
15 i <-- i + 1
16 else A[k] <-- R[j]
17 j <-- j + 1
我们尝试对两堆卡进行排序,但我们避免在每个基本步骤中检查堆是否为空,并且我们使用无限作为前哨卡来简化我们的代码。因此,每当前哨卡infinie曝光时,它不能是较小的卡,除非两个桩都暴露了他们的哨兵牌。但是一旦发生这种情况,所有非哨兵牌都已被放置在输出堆上。由于我们事先知道确切的r - p + 1
卡片将被放置在输出堆上,我们可以在执行了许多基本步骤后停止。
Loop Invariant:
初始化:在循环的第一次迭代之前,我们有k = p
,因此子数组A[p ... k - 1]
为空。这个空子阵列包含L和R的k - p = 0
个最小元素,自i = j = 1
起,L [i]和R [j]都是其数组中尚未复制回A的最小元素。
维护:要看到每次迭代都保持循环不变,我们首先假设l [i]&lt; = R [j]。然后L [i]是尚未复制回A的最小元素。因为A[p ... k - 1]
包含k - p
个最小元素,所以在第14行将L [i]复制到A [k]之后,子数组{{ 1}}将包含A[p ... k]
个最小元素。增加k(在for循环更新中)和i(在第15行中)重新建立下一次迭代的循环不变量。如果改为L [i]&gt; R [j],然后第16-17行执行适当的操作以保持循环不变。
终止:终止时,k - p + 1
。通过循环不变量,子k = r + 1
,A[p ... k - 1]
,按照排序顺序包含A[p ... r]
和k - p = r - p + 1
的{{1}}个最小元素。数组L和R一起包含L[1 ... n1 + 1]
个元素。除了两个最大的元素之外的所有元素都被复制回A,这两个最大的元素是哨兵。