数据结构和算法(六)循环不变式与插入排序证明 (算法导论读书笔记)


插入排序说明: 工作方式像排序一手扑克牌。开始时,左手为空并且桌子上的牌面向下。然后每次从桌子上拿走一张牌并将它插入左手中正确的位置。为了找到一张牌的正确位置,我们从右到左将它与自己手中的每张牌进行比较。

算法实现- 伪代码

INSERTION-SORT(A) A表示待排序的数组

 INSERTION-SORT(A)   
	for j = 2 to A.length {   
		key = A[j] // 拿起一张牌   
		// 将这张牌和手上的牌做比较 A[1...j-1]   
		i = j - 1   
		while i > 0 and a[i] > key {   
			A[i+1] = A[i]   
			i --   
		}   
		A[i+1] = key   
	} ​

循环不变式

在for循环每次迭代开始,子数组A[1…j-1]由原来在A[1…j-1]中的元素组成,但已按序排序。我们把A[1…j-i]称为循环不变式。 循环不变式主要用来帮助我们理解算法的正确性。关于循环不变式,我们必须证明三条性质:

  • 初始化:循环的第一次迭代之前,它为真。
  • 保持:如果循环的某次迭代之前它为真,那么下次迭代之前它仍为真。
  • 终止:在循环终止时,不变式为我们提供一个有用的性质,该性质有助于证明算法是正确的。

循环不变式插入排序正确性证明

  1. 初始化:第一次迭代之前,循环不变式成立。子数组A[1…j-1]仅由单个元素A[1]组成,该子数组是排序好的(只有一个元素,当然排序好的)。这表明第一次循环迭代之前,循环不变式成立。

  2. 保持:在while循环里面,我们将A[j-1]、A[j-2]、A[j-3]… 往后挪了一个位置,直到找到A[j]适当的位置,之后将A[j]插入该位置。子数组始终是 A[1…j-1],并已排序。那么for循环的下一次迭代增加j将保持循环不变式。

  3. 终止:首先终止条件是 j > A.length = n。因为每次循环迭代j加1,那么不终止的时候,必有 j = n + 1,而这个时候我们的子数组A[1…n]由原来的A[1…n]中的元素组成,并已排序。因此算法正确。


[1] 《算法导论》 机械工业出版社

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章