概述
(Hoare划分的正确性)本章中的PARTITION算法并不是其最初的版本。下面给出的是最早由C. R. Hoare所设计的划分算法:
a. 试说明HOARE-PARTITION在数组A = {13, 19, 9, 5, 12, 8, 7, 4, 11, 2, 6, 21}上的操作过程,并说明在每一次执行第4~14行while循环时数组元素的值和辅助变量的值。
后续的三个问题要求读者仔细论证HOARE-PARTITION的正确性。在这里假设子数组
A
[
p
.
.
r
]
A[p..r]
A[p..r]至少包含2个元素,试证明下列问题:
b. 下标
i
i
i和
j
j
j可以使我们不会访问在子数组
A
[
p
.
.
r
]
A[p..r]
A[p..r]以外的数组
A
A
A的元素。
c. 当HOARE-PARTITION结束时,它返回的值
j
j
j满足
p
≤
j
<
r
p ≤ j < r
p≤j<r。
d. 当HOARE-PARTITION结束时,
A
[
p
.
.
j
]
A[p..j]
A[p..j]中的每一个元素都小于或等于
A
[
j
+
1..
r
]
A[j+1..r]
A[j+1..r]中的元素。
在7.1节的PARTITION过程中,主元(原来存储在
A
[
r
]
A[r]
A[r]中)是与它所划分的两个分区分离的。与之对应,在HOARE-PARTITION中,主元(原来存储在
A
[
p
]
A[p]
A[p]中)是存在于分区
A
[
p
.
.
j
]
A[p..j]
A[p..j]或
A
[
j
+
1..
r
]
A[j+1..r]
A[j+1..r]中的。因为有
p
≤
j
<
r
p ≤ j < r
p≤j<r,所以这一划分总是非平凡的。
e. 利用HOARE-PARTITION,重写QUICKSORT算法。
解
a.
b.
虽然下标
i
i
i和
j
j
j分别被初始化为
p
−
1
p-1
p−1和
r
+
1
r+1
r+1,但是在第一轮while迭代中,
i
i
i会被先加1,而
j
j
j会被先减1,这样下标
i
i
i和
j
j
j分别从
p
p
p和
r
r
r开始。所以在迭代开始,下标
i
i
i和
j
j
j没有超出数组范围。
由于以首个元素作为划分主元,所以在第一轮while迭代中,
i
i
i会停留在
p
p
p,而
j
j
j会一直向左移动,直到遇到一个小于或等于
x
x
x的元素。下面分两种情况说明:
1) 如果
j
j
j在向左移动的过程中一直没有遇到小于或等于
x
x
x的元素,那么
j
j
j会一直向左移动直到
j
=
p
j = p
j=p为止,因为
A
[
p
]
=
x
A[p] = x
A[p]=x满足
j
j
j的停止条件。此时,由于
i
i
i一直停留在
p
p
p的位置,所以
i
=
j
i = j
i=j,故while迭代退出。在这个过程中,
i
i
i和
j
j
j都没有超出数组
A
[
p
.
.
r
]
A[p..r]
A[p..r]的范围。
2) 如果
j
j
j遇到了一个小于或等于
x
x
x的元素 (该元素不为
A
[
p
]
A[p]
A[p]),那么
A
[
j
]
A[j]
A[j]与
A
[
i
]
A[i]
A[i] (
A
[
i
]
A[i]
A[i]即
A
[
p
]
A[p]
A[p]) 交换。这说明在下标
j
j
j的左侧至少有一个小于或等于
x
x
x的元素,并且在下标
i
i
i的右侧至少有一个大于或等于
x
x
x的元素,这可保证
i
i
i和
j
j
j在移动过程中不会超出数组范围。
c.
在第一轮while迭代中,下标
i
i
i一定会停留在
p
p
p,而下标
j
j
j分2种情况:
1) 如果
j
j
j在
r
r
r位置停留下来了,此时有
i
<
j
i < j
i<j (因为已经假设数组元素不少于2个),那么交换
A
[
i
]
A[i]
A[i]和
A
[
j
]
A[j]
A[j],继续进行第二轮while迭代。在第二轮while迭代中,
j
j
j一定至少向左移动一个位置,故一定有
j
<
r
j < r
j<r。
2) 如果
j
j
j没有在
r
r
r位置停留,而是继续向左移动,此时也有
j
<
r
j < r
j<r。
再根据b的结论,
j
j
j不会超出数组范围,故
j
≥
p
j ≥ p
j≥p。所以
j
j
j一定满足
p
≤
j
<
r
p ≤ j < r
p≤j<r。
d.
先给出循环不变式:在每轮while迭代开始之前,
A
[
p
.
.
i
]
A[p .. i]
A[p..i]中的元素都小于或等于
x
x
x,并且
A
[
j
.
.
r
]
A[j .. r]
A[j..r]中的元素都大于或等于
x
x
x。这个循环不变式应该不难证明,这里省略证明过程。
下面分析while迭代的终结时的情况。在while迭代中,代码第5 ~ 7行的repeat迭代和第8~10行的repeat迭代结束时,必然有
A
[
p
.
.
i
−
1
]
A[p..i-1]
A[p..i−1]中的元素都小于或等于
A
[
j
+
1..
r
]
A[j+1..r]
A[j+1..r]中的元素。在最后一次while迭代中,repeat迭代结束后,必然有
i
=
j
i = j
i=j或
i
=
j
+
1
i = j+1
i=j+1。如果
i
=
j
i = j
i=j,那么必然有
A
[
i
]
=
x
A[i] = x
A[i]=x,由于
A
[
p
.
.
i
−
1
]
A[p..i-1]
A[p..i−1]中的元素都小于或等于
A
[
j
+
1..
r
]
A[j+1..r]
A[j+1..r]中的元素,将
A
[
i
]
A[i]
A[i]加入
A
[
p
.
.
i
−
1
]
A[p..i-1]
A[p..i−1],于是有
A
[
p
.
.
i
]
A[p..i]
A[p..i] (即
A
[
p
.
.
j
]
A[p..j]
A[p..j]) 中的元素都小于或等于
A
[
j
+
1..
r
]
A[j+1..r]
A[j+1..r]中的元素。如果
i
=
j
+
1
i = j+1
i=j+1,那么
j
=
i
−
1
j = i-1
j=i−1,于是有
A
[
p
.
.
j
]
A[p..j]
A[p..j]中的元素都小于或等于
A
[
j
+
1..
r
]
A[j+1..r]
A[j+1..r]中的元素。
e.
代码链接:https://github.com/yangtzhou2012/Introduction_to_Algorithms_3rd/tree/master/Chapter07/Problem_7-1
最后
以上就是殷勤乌龟为你收集整理的算法导论 — 思考题 7-1 Hoare划分的正确性的全部内容,希望文章能够帮你解决算法导论 — 思考题 7-1 Hoare划分的正确性所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复