算法导论 — 思考题 7-1 Hoare划分的正确性

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] 至少包含2个元素,试证明下列问题:
  b. 下标 i i j j 可以使我们不会访问在子数组 A [ p . . r ] A[p..r] 以外的数组 A A 的元素。
  c. 当HOARE-PARTITION结束时,它返回的值 j j 满足 p j < r p ≤ j < r
  d. 当HOARE-PARTITION结束时, A [ p . . j ] A[p..j] 中的每一个元素都小于或等于 A [ j + 1.. r ] A[j+1..r] 中的元素。
  在7.1节的PARTITION过程中,主元(原来存储在 A [ r ] A[r] 中)是与它所划分的两个分区分离的。与之对应,在HOARE-PARTITION中,主元(原来存储在 A [ p ] A[p] 中)是存在于分区 A [ p . . j ] A[p..j] A [ j + 1.. r ] A[j+1..r] 中的。因为有 p j < r p ≤ j < r ,所以这一划分总是非平凡的。
  e. 利用HOARE-PARTITION,重写QUICKSORT算法。
  
  
  a.
  在这里插入图片描述
  
  b.
  虽然下标 i i j j 分别被初始化为 p 1 p-1 r + 1 r+1 ,但是在第一轮while迭代中, i i 会被先加1,而 j j 会被先减1,这样下标 i i j j 分别从 p p r r 开始。所以在迭代开始,下标 i i j j 没有超出数组范围。
  由于以首个元素作为划分主元,所以在第一轮while迭代中, i i 会停留在 p p ,而 j j 会一直向左移动,直到遇到一个小于或等于 x x 的元素。下面分两种情况说明:
  1) 如果 j j 在向左移动的过程中一直没有遇到小于或等于 x x 的元素,那么 j j 会一直向左移动直到 j = p j = p 为止,因为 A [ p ] = x A[p] = x 满足 j j 的停止条件。此时,由于 i i 一直停留在 p p 的位置,所以 i = j i = j ,故while迭代退出。在这个过程中, i i j j 都没有超出数组 A [ p . . r ] A[p..r] 的范围。
  2) 如果 j j 遇到了一个小于或等于 x x 的元素 (该元素不为 A [ p ] A[p] ),那么 A [ j ] A[j] A [ i ] A[i] ( A [ i ] A[i] A [ p ] A[p] ) 交换。这说明在下标 j j 的左侧至少有一个小于或等于 x x 的元素,并且在下标 i i 的右侧至少有一个大于或等于 x x 的元素,这可保证 i i j j 在移动过程中不会超出数组范围。
  
  c.
  在第一轮while迭代中,下标 i i 一定会停留在 p p ,而下标 j j 分2种情况:
  1) 如果 j j r r 位置停留下来了,此时有 i < j i < j (因为已经假设数组元素不少于2个),那么交换 A [ i ] A[i] A [ j ] A[j] ,继续进行第二轮while迭代。在第二轮while迭代中, j j 一定至少向左移动一个位置,故一定有 j < r j < r
  2) 如果 j j 没有在 r r 位置停留,而是继续向左移动,此时也有 j < r j < r
  再根据b的结论, j j 不会超出数组范围,故 j p j ≥ p 。所以 j j 一定满足 p j < r p ≤ j < r
  
  d.
  先给出循环不变式:在每轮while迭代开始之前, A [ p . . i ] A[p .. i] 中的元素都小于或等于 x x ,并且 A [ j . . r ] A[j .. r] 中的元素都大于或等于 x x 。这个循环不变式应该不难证明,这里省略证明过程。
  下面分析while迭代的终结时的情况。在while迭代中,代码第5 ~ 7行的repeat迭代和第8~10行的repeat迭代结束时,必然有 A [ p . . i 1 ] A[p..i-1] 中的元素都小于或等于 A [ j + 1.. r ] A[j+1..r] 中的元素。在最后一次while迭代中,repeat迭代结束后,必然有 i = j i = j i = j + 1 i = j+1 。如果 i = j i = j ,那么必然有 A [ i ] = x A[i] = x ,由于 A [ p . . i 1 ] A[p..i-1] 中的元素都小于或等于 A [ j + 1.. r ] A[j+1..r] 中的元素,将 A [ i ] A[i] 加入 A [ p . . i 1 ] A[p..i-1] ,于是有 A [ p . . i ] A[p..i] (即 A [ p . . j ] A[p..j] ) 中的元素都小于或等于 A [ j + 1.. r ] A[j+1..r] 中的元素。如果 i = j + 1 i = j+1 ,那么 j = i 1 j = i-1 ,于是有 A [ p . . j ] A[p..j] 中的元素都小于或等于 A [ j + 1.. r ] A[j+1..r] 中的元素。
  
  e.
  在这里插入图片描述

代码链接:https://github.com/yangtzhou2012/Introduction_to_Algorithms_3rd/tree/master/Chapter07/Problem_7-1

猜你喜欢

转载自blog.csdn.net/yangtzhou/article/details/85255342
今日推荐