插入排序伪代码
INSERTION-SORT(A)
for j = 2 to A.length
key = A[j]
i = j - 1
while i > 0 and A[i] > key
A[i+1] = A[i]
i = i - 1
A[i + 1] = key

伪代码的一些约定
1.缩进表示块结构
2.for循环迭代增加使用to,减少用downto
3.若无显式说明,不使用全局变量
4.数组不指向任何对象,赋值NIL

循环不变式
在INSERTION-SORT 的for循环中,循环变量为j。j代表当前正要被插入到序列中的元素的下标。而子数组A[1~j-1]是已经被排好序的子序列。这一性质,在j被赋予初值2,首次进入循环之前成立,而且每次循环之后(j加了1)、进入下一次循环之前也成立。

在第一次进入循环之前成立、每次循环之后还成立的关系称为“循环不变式”

可以利用循环不变关系证明循环的正确性。
分三步走:
1)初始化:证明初始状态时循环不变式成立,即证明循环不变式在循环开始之前为真;
2)保持:即证明每次循环之后、下一次循环开始之前循环不变式仍为真;
3)终止:即证明循环可以在有限次循环之后终止。

其中第1)和2)步类似于数学归纳法的证明策略

分治法
思想:将原问题分解为几个规模较小、但类似于原问题的子问题,递归地求解这些子问题,然后再合并这些子问题的解以建立原问题的解
1)分解 2)解决 3)合并

实例:归并排序
算法入门(2)
算法入门(2)
归并排序的时间分析:T(n)=2T(n/2)+cn = O(nlogn)
当子问题足够小时,不需要再进一步分解,则称之为基本情况(base case)。基本情况的子问题可以直接求解。
但若子问题还足够大,不能直接求解,则需要进一步分解子问题并递归求解,称之为递归情况(recursive case)。
分治的基本思想就是递归求解策略

最大子数组问题
过程1:FIND-MAX-CROSSING-SUBARRAY,求跨越中点的最大子数组
算法入门(2)
过程2: FIND-MAXIMUM-SUBARRAY ,求最大子数组问题的分治算法
算法入门(2)
此处将数组分解为左右两个子数组,求左右两个子数组的方法相同。之后只需要判断最大子数组是否跨越中点,三者比较就可以得出结果。
FIND-MAXIMUM-SUBARRAY的执行时间T(n)的递归式
算法入门(2)
由此得出算法入门(2)

Strassen矩阵乘法
普通矩阵乘法 8次乘法,4次相加
算法入门(2)
T(n) = O(n3)

Strassen矩阵乘法,对于2x2矩阵,乘法次数:7次,加(减)法次数:18次
算法入门(2)
T(n) = Ο(nlog7)≈Ο(n2.81)

求解递归式
三种方法:代换法,递归树法,主方法

1.代换法
步骤:
(1) 猜测解的形式
(2) 用数学归纳法证明猜测的正确性
例如 化简算法入门(2)
做代数代换:令m=logn ,则n=2m

2.递归树法
递归树:反应递归的执行过程。每个节点表示一个单一子问题的代价,子问题对应某次递归调用,根节点代表顶层调用的代价,子节点分别代表各层递归调用的代价。

例:已知递归式算法入门(2)
用递归树描述T(n)的演化过程:
算法入门(2)
整棵树的总代价等于各层代价之和

3.主方法
如果递归式有如下形式,在满足一定的条件下,可以用主方法直接给出渐近界算法入门(2)
其中,a、b是常数,且a≥1,b>1;f(n)是一个渐近正的函数
算法入门(2)
f(n)和*比较,T(n)取了其中较大的一个。两个函数一样大,则乘以对数因子

相关文章: