其他
算法导论 | 循环不变式与插入排序
我们在学习算法阶段第一个要解决的问题就是排序,也就是把一个由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: 学算法真费脑,昨天吃完晚饭看了一个小时,肚子就饿了。
作业:
我的代码输入结果式升序的,请尝试写出降序,编程语言随意
假设你有已经排序的序列A,给定一个数值,查找该数值在A的位置,如果找不到则返回NIL。代码应该如何写