數據結構和算法(六)循環不變式與插入排序證明 (算法導論讀書筆記)


插入排序說明: 工作方式像排序一手撲克牌。開始時,左手爲空並且桌子上的牌面向下。然後每次從桌子上拿走一張牌並將它插入左手中正確的位置。爲了找到一張牌的正確位置,我們從右到左將它與自己手中的每張牌進行比較。

算法實現- 僞代碼

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] 《算法導論》 機械工業出版社

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