算法导论学习笔记1_循环不变式

1. 循环不变式和数学归纳法

在数学中,数学归纳法常用于证明给定命题在自然数范围内的正确性,它是一种严谨的演绎推理法。而在计算机科学中,循环不变式同样作为一种演绎推理法用于理解和证明算法的正确性。从下文的介绍中可以看出,循环不变式和数学归纳法有着许多的相似之处。

2. 循环不变式的三条性质

循环不变式用于理解和证明算法的正确性。实际上,循环不变式并不是狭义上的一个式子,而是一个在命题,一个在算法的起始状态、运行过程中和算法结束时始终保持为真的一个命题。通过下文中的例子可以更加清晰的认识到循环不变式的意义,下面是循环不变式的三条性质:

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

注意:循环不变式的前两条性质类似于数学归纳法,证明了一个基本情况和一个归纳步。此外,终止性不同于数学归纳法的做法,在归纳法中,归纳步是无限地使用的,这里当循环终止的时候,归纳随之终止。

3. 利用循环不变式分析插入排序

插入排序是一个简单的原址排序算法,也是一种稳定的排序算法。下面给出插入排序的伪代码,然后利用循环不变式来分析算法的正确性。

INSERT-SORT(A)
	for j = 2 to A.length
		key = A[j]
		// 将第j个数插入到前j-1个已排序的数中
		i = j - 1
		while i > 0 and A[i] > key
			A[i + 1] = A[i]
			i = i - 1
		A[i + 1] = key

循环不变式:在for循环的每次迭代开始时,子数组A[1…j-1]由原来在A[1…j-1]中的元素组成,但已按升序排列。

下面证明循环不变式的三条性质成立:
初始化循环的第一次迭代之前,循环不变式成立。当第一次迭代之前(j = 2),A[1…j-1]就是A[1],即初始的第一个元素,循环不等式显然成立。
保持如果循环的某次迭代之前它为真,那么下次迭代之前它仍为真。这里假设A[1…j-1]由原来的A[1…j-1]中元素组成,且已按升序排列。那么在此次循环中,将A[j-1]、A[j-2]、A[j-3]等元素逐个向右移动一个位置,直到找到A[j]的适宜位置为止,然后将A[j]的值插入该位置。此时,A[1…j]仍有原来在A[1…j]中的元素组成,且已按升序排列。因此,在下次迭代之前,循环不变式仍然为真。
终止:循环终止时j = A.length + 1。由循环不变式可知,A[1…A.length]由原来在A[1…A.length]中的元素组成,但已按升序排列。由于A[1…A.length]就是整个数组,因此整个数组已按升序排列,算法正确。

注意:循环不变式的判定是在每次迭代之前,在上例中我们以for循环中对循环变量j赋值之后,对循环变量判断终止条件之前这一时刻为迭代之前的时刻。因此,在循环终止之前时,循环变量j = A.length+1,此时数组A[1…A.length]由原来在A[1…A.length]的元素组成,且按升序排序。

4. 练习题

2.1.3

考虑以下查找问题
入:n个数的一个序列 A = &lt; a 1 , a 2 , . . . , a n &gt; 和 一 个 值 v 。 A=&lt;a_1, a_2, ..., a_n&gt;和一个值v。 A=<a1,a2,...,an>v
输出:下标i使得 v = A [ i ] v=A[i] v=A[i]或者当 v v v不在A中出现时, i i i为特殊值NIL。
写出线性查找的伪代码,它扫描整个序列来查找 v v v。使用一个循环不变式来证明你的算法是正确的。确保你的循环不变式满足三条必要的性质。

1.伪代码:

LINEAR-SEARCH(A, v)
	for j = 1 to A.length
		if v == A[j]
			return j
	return NIL

2.循环不变式:在for循环的每次迭代开始,子数组 A [ 1.. j − 1 ] A[1..j-1] A[1..j1]中不存在值 v v v
3.证明:
初始化:第一次迭代前 j = 1 , A [ 1..0 ] j=1,A[1..0] j=1A[1..0]为空,循环不变式显然成立。
保持:假设第 k k k次迭代前循环不等式成立,即 A [ 1.. k − 1 ] A[1..k-1] A[1..k1]中不存在值 v v v。在此次循环中,如果 A [ j ] = v A[j]=v A[j]=v,则算法结束,返回当前值的下标j;如果 A [ j ] ≠ v A[j]≠v A[j]̸=v,则子数组 A [ 1.. k ] A[1..k] A[1..k]中不存在值 v v v,在下一次迭代开始之前,循环不变式成立。
终止:循环终止存在两种情况,一种就是迭代过程中查找到目标元素,则返回该元素在数组种的下标。另一种是数组种不存在目标元素,在循环终止前j=A.length+1,由循环不变式得数组 A [ 1.. A . l e n g t h ] A[1..A.length] A[1..A.length]种不存在值 v v v,即 v v v不存在与数组A中,于是程序运行到最后返回特殊值NIL。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值