循环不变式

目录

何为循环不变式

理解循环不变式

循环不变式的性质

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


何为循环不变式

        循环不变式 (loop invariant) 用于理解和证明算法的正确性。实际上,循环不变式并不是狭义上的式子,而是一个在算法起始、中间运算、中止的过程中保持为“真”的命题。即在循环体的每次执行前后均为真的谓词。循环不变式体现了循环程序中循环变量的变化规律。

理解循环不变式

        举例说明:口袋中有黑、白两色小球,现将手放入袋中每次摸出两个,如果两球同色就都不放回袋中,如果两球异色就将白球放回,由于每次至少减少一个,所以袋中的球必然越来越少。现问:如果袋中最后剩下一个球,此球的颜色与开始时袋中黑、白球的个数有什么关系?按照一般的思路,此题非常复杂,难以解决。多次重复摸球及放回的动作构成了一个循环过程。如果我们有意识地寻找循环过程中不变的性质,就会发现,在循环过程中,白球个数的奇偶性保持不变,因为,每次取出的白球的个数或是零或是2。因此,如果开始时白球的个数为奇数,那么剩下的一球为白球。如果开始时白球的个数为偶数,那么剩下的一球为黑球。

        这种不依较前面所执行的重复次数的性质称之为循环不变式。

循环不变式的性质

        关于循环不变式,我们需要证明三条性质:


        初始化:循环的第一次迭代之前,它为真。

        保持:如果循环的某次迭代之前它为真,那么下次迭代之前它仍为真。

        终止:在循环终止时,不变式为我们提供一个有用的性质,该性质有助于证明算法是否是正确的。


前两条性质有点类似于数学归纳法,但第三条性质与我们通常使用的数学归纳法不同,在归纳法中,归纳步是无限使用的,但在这里当循环终止时,停止“归纳”。

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

        插入排序 (insertion sort) 是一种简单的排序算法,下面利用循环不变式证明插入排序的正确性。

插入排序的伪代码如下:

INSERTION-SORT(A)
    for j = 2 to A.length
        key = A[j]
        //将A[j]插入到排序后的A[1..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]中的元素组成,但已按升序排列。

        接着证明循环不变式的三条性质成立:

        初始化:在循环的第一次迭代之前,子数组A[1..j-1]仅由第一个元素A[1]组成,循环不变式显然成立。

        保持:在循环中,将A[ j - 1]、A[ j - 2]、A[ j - 3]等向右移动一个位置,直到A[j]找到适当位置,并将A[ j ]插入到该位置。此时子数组A[1.. j ]由原来在A[1.. j ]中的元素组成,但已按序排列。循环不变式成立。

        终止:循环终止的条件为 j >A.length=n。即 j =A.length+1时。此时子数组A[1.. n ]由原来在A[1.. n ]中的元素组成,但已按序排列。循环不变式成立,算法正确。

e4b69711bf0b453cb514f4460461fc12.png

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

#include <bug>

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值