查看原文
其他

算法导论 | 循环不变式与插入排序

2017-08-30 徐洲更 生信媛

我们在学习算法阶段第一个要解决的问题就是排序,也就是把一个由n个数组成的序列顺序或逆序排列。

插入排序

插入排序是最容易想到的算法,因为在平时最常使用。比如说在打扑克的时候,每次抽一张牌,和左手已经有的牌逐个比较,直到找不到更小的为止。R代码如下

insert.sort <- function(x){  # 先抽一张牌    arr <- x[1]  
   for (i in seq(2,length(x))){    
   # 以此抽取列表x的值    value <- x[i]    
   # 当我们抽了i张牌的时候,左手已经有i-1张牌    j <- i - 1    # 如果前面还有牌,并且抽的牌比前面的小    while(j > 0 & arr[j] > value ) {    
   # 把之前的牌放在最后的位置      arr[j+1] <- arr[j]    
   # 则将这张牌放在之前的位置上    # 继续将这张牌和之前的牌进行比较      j <- j -1    }    
  # 找不到了就把前一个位置给他    arr[j+1] <- value  }  arr }

这个算法虽然简单,但它符合循环不变式的三个性质:初始,保持,终止

  • 在初始时,循环不变式成立。在这里就是抽第一张牌的时候成立

  • 保持意味着每次循环开始,循环不变式成立,结束后循环不变式也成立。在这里为每抽一张牌之前,左手的牌都是排序的,并且在抽下一张牌前,左手的牌也经过了排序。

  • 循环不变式不能无限运行,必须有一个终止条件。这里就是当你把牌全部抽完。

其中初始和保持这两条性质类似于高中学过的数学归纳法。

- 当n=1的时候,等式成立,

- 假设n时等式成立,那么只要证明n+1时,等式也成立的话,对于任意正整数,该等式也成立。

不过数学归纳法可以无穷无尽,而循环一定要有终止的时刻,不然费电。

本次就介绍排序算法,下次介绍如何归并排序和分治法。

PS: 学算法真费脑,昨天吃完晚饭看了一个小时,肚子就饿了。

作业:

  1. 我的代码输入结果式升序的,请尝试写出降序,编程语言随意

  2. 假设你有已经排序的序列A,给定一个数值,查找该数值在A的位置,如果找不到则返回NIL。代码应该如何写

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存