1、插入排序
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
循环不变式为:for循环的每次迭代开始时,子数组A[1…j-1]由原来在A[1…j-1]中的元素组成,但以按序排列。
初始化:对循环技术变量的初始赋值后、在循环头的第一次测试之前,保持循环不变式。
保持:每次迭代保持循环不变式。
终止:循环终止时保持循环不变式。
T
=
O
(
n
2
)
T=O(n^2)
T=O(n2)
2、渐进记号
(1)
Θ
\Theta
Θ记号:渐进紧确界
(2)
O
O
O记号:渐进上界
(3)
Ω
\Omega
Ω记号:渐进下界
3.1 代入法求解递归式
例题:
T
(
n
)
=
4
T
(
n
/
2
)
+
n
T(n)=4T(n/2)+n
T(n)=4T(n/2)+n
猜测:
T
(
n
)
=
O
(
n
3
)
T(n)=O(n^3)
T(n)=O(n3)
假设
T
(
k
)
≤
c
k
3
T(k)\leq ck^3
T(k)≤ck3,对于
k
<
n
k<n
k<n
证明存在
c
>
0
c>0
c>0,使得
T
(
n
)
≤
c
n
3
T(n)\leq cn^3
T(n)≤cn3
证:
T
(
n
)
=
4
T
(
n
/
2
)
+
n
≤
4
c
(
n
/
2
)
3
+
n
=
c
n
3
−
(
(
c
/
2
)
n
3
−
n
)
≤
c
n
3
T(n)=4T(n/2)+n\leq4c(n/2)^3+n=cn^3-((c/2)n^3-n) \leq cn^3
T(n)=4T(n/2)+n≤4c(n/2)3+n=cn3−((c/2)n3−n)≤cn3
要使
(
c
/
2
)
n
3
−
n
≥
0
(c/2)n^3-n\geq0
(c/2)n3−n≥0,有
c
≥
2
,
且
n
≥
1
c\geq2,且n\geq1
c≥2,且n≥1
3.2 递归树法求解递归式
将树中每层中的代价求和,得到每层代价,然后将所有层的代价求和,得到所有层次的递归调用的总代价。书P50
3.3 主方法求解递归式
主方法适用于下面的递归形式:
T
(
n
)
=
a
T
(
n
/
b
)
+
f
(
n
)
,
其
中
a
≥
1
,
和
b
>
1
T(n)=aT(n/b)+f(n),其中a\geq1,和b>1
T(n)=aT(n/b)+f(n),其中a≥1,和b>1是常数,
f
(
n
)
f(n)
f(n)是渐进正函数
将
f
(
n
)
与
n
log
b
a
f(n)与n^{\log_b a}
f(n)与nlogba进行比较:
(1)
f
(
n
)
=
O
(
n
log
b
a
−
ε
)
即
f
(
n
)
<
n
log
b
a
时
,
f
(
n
)
比
n
log
b
a
增
长
的
慢
:
f(n)=O(n^{\log_b a-\varepsilon})即f(n)<n^{\log_b a}时,f(n)比n^{\log_ba}增长的慢:
f(n)=O(nlogba−ε)即f(n)<nlogba时,f(n)比nlogba增长的慢:
T
(
n
)
=
Θ
(
n
log
b
a
)
T(n)=\Theta(n^{\log_ba})
T(n)=Θ(nlogba)
(2)
f
(
n
)
=
Θ
(
n
log
b
a
)
即
f
(
n
)
=
n
log
b
a
时
,
f
(
n
)
和
n
log
b
a
lg
n
增
长
速
度
相
同
:
f(n)=\Theta(n^{\log_ba})即f(n)=n^{\log_ba}时,f(n)和n^{\log_ba} \lg n增长速度相同:
f(n)=Θ(nlogba)即f(n)=nlogba时,f(n)和nlogbalgn增长速度相同:
T
(
n
)
=
Θ
(
n
log
b
a
lg
n
)
T(n)=\Theta(n^{\log_ba} \lg n)
T(n)=Θ(nlogbalgn)
(3)
f
(
n
)
=
Ω
(
n
log
b
a
+
ε
)
即
f
(
n
)
>
n
log
b
a
时
,
f
(
n
)
比
n
log
b
a
增
长
的
快
:
f(n)=\Omega(n^{\log_b a+\varepsilon})即f(n)>n^{\log_b a}时,f(n)比n^{\log_ba}增长的快:
f(n)=Ω(nlogba+ε)即f(n)>nlogba时,f(n)比nlogba增长的快:
T
(
n
)
=
Θ
(
f
(
n
)
)
T(n)=\Theta(f(n))
T(n)=Θ(f(n))
4、分治法
(1)将问题分解为子问题
(2)递归地求解子问题
(3)组合子问题的答案
举例:
- 合并排序: T ( n ) = 2 T ( n / 2 ) + Θ ( n ) = Θ ( n lg n ) T(n)=2T(n/2)+\Theta(n)=\Theta(n\lg n) T(n)=2T(n/2)+Θ(n)=Θ(nlgn)
- 二分查找: T ( n ) = 1 T ( n / 2 ) + Θ ( 1 ) = Θ ( lg n ) T(n)=1T(n/2)+\Theta(1)=\Theta(\lg n) T(n)=1T(n/2)+Θ(1)=Θ(lgn)
- 求幂: T ( n ) = 2 T ( n / 2 ) + Θ ( 1 ) = Θ ( n ) T(n)=2T(n/2)+\Theta(1)=\Theta(n) T(n)=2T(n/2)+Θ(1)=Θ(n)
- 计算斐波那契数: T ( n ) = Θ ( lg n ) T(n)=\Theta(\lg n) T(n)=Θ(lgn)
- 矩阵相乘: n × n 矩 阵 = 2 × 2 个 ( n / 2 ) × ( n / 2 ) 矩 阵 , T ( n ) = 8 T ( n / 2 ) + Θ ( n 2 ) n\times n矩阵=2\times2个(n/2)\times (n/2)矩阵,T(n)=8T(n/2)+\Theta(n^2) n×n矩阵=2×2个(n/2)×(n/2)矩阵,T(n)=8T(n/2)+Θ(n2) , T ( n ) = Θ ( n 3 ) T(n)=\Theta(n^3) T(n)=Θ(n3)
SQUARE-MATRIX-MULTIPLY(A,B)
n=A.rows
let C be a new nXn matrix
for i=1 to n
for j=1 to n
c[i][j] = 0
for k=1 to n
c[i][j] += A[i][k] * B[k][j]
return C
- 矩阵乘法的Strassen算法:递归地进行7个
(
n
/
2
)
×
(
n
/
2
)
子
矩
阵
相
乘
,
T
(
n
)
=
7
T
(
n
/
2
)
+
Θ
(
n
2
)
=
Θ
(
n
lg
7
)
≈
n
2.81
(n/2)\times (n/2)子矩阵相乘,T(n)=7 T(n/2)+\Theta(n^2)=\Theta(n^{\lg7})\approx n^{2.81}
(n/2)×(n/2)子矩阵相乘,T(n)=7T(n/2)+Θ(n2)=Θ(nlg7)≈n2.81 迄今为止最好的最好的算法是
T
(
n
)
=
Θ
(
n
2.376
)
T(n)=\Theta(n^{2.376})
T(n)=Θ(n2.376)
5、快速排序
QUICKSORT(A,p,r)
if p<r
q=PARTITION(A,p,r)
QUICKSORT(A,p,q-1)
QUICKSORT(A,q+1,r)
PARTITION(A,p,q)
x=A[p]
i=p
for j=p+1 to q
do if A[j] <= x
then i=i+1
exchange A[i] <-> A[j]
exchange A[p] <-> A[i]
return i
直接调用QUICKSORT(A,1,n)
快速排序期望运行时间:
T
(
n
)
=
O
(
n
lg
n
)
T(n)=O(n\lg n)
T(n)=O(nlgn),最坏情况:
T
(
n
)
=
Θ
(
n
2
)
T(n)=\Theta(n^2)
T(n)=Θ(n2)
PARTITION的时间复杂度
T
(
n
)
=
Θ
(
n
)
T(n)=\Theta(n)
T(n)=Θ(n)
PARTITION循环不变量:对于任意数组下标k,有:
(1)
若
p
+
1
≤
k
≤
i
,
则
A
[
k
]
≤
x
若p+1\leq k\leq i,则A[k]\leq x
若p+1≤k≤i,则A[k]≤x
(2)
若
i
+
1
≤
k
≤
j
−
1
,
则
A
[
k
]
>
x
若i+1\leq k\leq j-1,则A[k]>x
若i+1≤k≤j−1,则A[k]>x
(3)
若
k
=
p
,
则
A
[
k
]
=
x
若k=p,则A[k]=x
若k=p,则A[k]=x
6、计数排序
COUNTING-SORT(A,B,k)
for i=1 to k
do C[i] = 0
for j=1 to n
do C[A[j]] = C[A[j]]+1
for i=2 to k
do C[i] = C[i] + C[i-1]
for j=n downto 1
do B[C[A[j]]] = A[j]
C[A[j]] = C[A[j]] - 1
T ( n ) = Θ ( n + k ) T(n)=\Theta(n+k) T(n)=Θ(n+k),计数排序是稳定的排序
7、基数排序
RADIX-SORT(A,d)
for i=1 to d
use a stable sort to sort array A on digit i
T ( n ) = Θ ( d ( n + k ) ) , 其 中 d 为 数 字 的 最 高 位 数 T(n)=\Theta(d(n+k)),其中d为数字的最高位数 T(n)=Θ(d(n+k)),其中d为数字的最高位数
8、二叉搜索树
二叉搜索树的期望高度为
O
(
lg
n
)
O(\lg n)
O(lgn),也为二叉搜索树的搜索时间
遍历有n个结点的二叉搜索树需要
Θ
(
n
)
\Theta(n)
Θ(n)的时间
9、红黑树
红黑树的性质:
(1)任何一个结点要么是黑的要么是红的。
(2)根和叶子(NIL)是黑的。
(3)如果一个结点是红的,那么它的父亲是黑的。
(4)从任何一个结点x到它的后代叶子的简单路径上的黑结点的数目是相同的=black-height(x)
一棵有n个键的红黑树高度
h
≤
2
lg
(
n
+
1
)
h\leq 2\lg (n+1)
h≤2lg(n+1)
SEARCH、MINIMUM、MAXIMUM、SUCCESSOR(后继)、PREDECESSOR(前驱)在红黑树上的时间复杂度
T
(
n
)
=
O
(
lg
n
)
T(n)=O(\lg n)
T(n)=O(lgn)
9.1红黑树的旋转
T
(
n
)
=
O
(
1
)
T(n)=O(1)
T(n)=O(1)
9.2红黑树的插入
将15插入树,15为红色
红黑树的插入情况1:直接重新着色
红黑树的插入情况2:左旋转
红黑树的插入情况3:右旋转
10、顺序统计树
O
S
−
S
E
L
E
C
T
(
i
,
S
)
:
查
找
以
S
为
根
的
第
i
小
的
关
键
字
的
结
点
,
T
(
n
)
=
O
(
lg
n
)
OS-SELECT(i,S):查找以S为根的第i小的关键字的结点,T(n)=O(\lg n)
OS−SELECT(i,S):查找以S为根的第i小的关键字的结点,T(n)=O(lgn)
O
S
−
R
A
N
K
(
x
,
S
)
:
返
回
以
S
为
根
的
关
键
字
为
x
的
结
点
的
位
置
,
T
(
n
)
=
O
(
lg
n
)
OS-RANK(x,S):返回以S为根的关键字为x的结点的位置,T(n)=O(\lg n)
OS−RANK(x,S):返回以S为根的关键字为x的结点的位置,T(n)=O(lgn)
11、动态规划
(1)最优子结构
(2)重叠子问题
LCS的递归代码:
LCS(x,y,i,j)
if x[i] = y[j]
then c[i,j] = LCS(x,y,i-1,j-1) + 1
else c[i,j] = max{LCS(x,y,i-1,j),LCS(x,y,i,j-1)}
T
(
n
)
=
O
(
m
+
n
)
T(n)=O(m+n)
T(n)=O(m+n)
LCS的备忘录代码:
LCS(x,y,i,j)
if c[i,j] = NIL
then if x[i] = y[j]
then c[i,j] = LCS(x,y,i-1,j-1) + 1
else c[i,j] = max{LCS(x,y,i-1,j),LCS(x,y,i,j-1)}
P224
带备忘的自上而下的递归的矩阵链排序:
T
(
n
)
=
O
(
n
3
)
T(n)=O(n^3)
T(n)=O(n3)
MEMOIZED-MATRIX-CHAIN(p)
n = p.length-1
let m[1..n,1..n]be a new table
for i=1 to n
for j=i to n
m[i,j] = ∞
return LOOKUP-CHAIN(m,p,1,n)
LOOKUP-CHAIN(m,p,i,j)
if m[i,j] < ∞
return m[i,j]
if i==j
m[i,j]=0
else for k=i to j-1
q = LOOKUP-CHAIN(m,p,i,k) + LOOKUP-CHAIN(m,p,k+1,j) + p[i-1]*p[k]*p[j]
if q < m[i,j]
m[i,j] = q
return m[i,j]
12、贪心算法
(1)最优子结构
(2)贪心选择性质
- 顶点覆盖
- 活动选择 T ( n ) = O ( n ) T(n)=O(n) T(n)=O(n)
- 哈夫曼编码
T
(
n
)
=
O
(
n
lg
n
)
T(n)=O(n\lg n)
T(n)=O(nlgn)
13、平摊分析
动态表: n个插入的最坏代价
T
(
n
)
=
Θ
(
n
)
T(n)=\Theta(n)
T(n)=Θ(n)
三种常用的平摊分析方法:
(1)聚集法
(2)记账法
(3)势能法
14.1二项树
14.2二项堆
二项堆是由一组满足二项堆性质的二项树组成
15、NP完全性
- P类问题:多项式时间内可解的问题
- NP类问题:多项式时间内可验证的问题
- NP-complete问题:
其中(2)为所有NP问题在多项式时间内可以归约到L
- 若L满足上诉(2)性质,但不一定满足性质(1),则称L是NP-hard问题