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


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

算法实现- 代码

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

for (int j = 1; j < array.length; j ++) {
    int key = array[j];
    // 将这张牌和手上的牌做比较 A[1...j-1]
    int i = j - 1;
    while (i >= 0 && array[i] > key) {
        array[i + 1] = array[i];
        i --;
    }
    array[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] 《算法导论》 机械工业出版社

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值