笔记
在应用代入法求解递归式时,需要事先做出一个好的猜测。然而,有时候做出好的猜测是很困难的,此时可以考虑采用递归树方法。在递归树中,每个结点表示一个单一子问题的代价。创建递归树之后,对树的每层的各子问题的代价进行求和,得到每一层的代价,然后将所有层的代价加起来,得到整棵递归树的总代价,这个总代价就是递归式的解。当然,递归树方法是一种粗略的方法,因为递归树会引入一些“不精确”因素,这一点在后文再详细介绍。如果要精确求解递归式,还需要用代入法对递归树得到的解进行验证。
以递归式
T
(
n
)
=
3
T
(
⌊
n
/
4
⌋
)
+
Θ
(
n
2
)
T(n)=3T(⌊n/4⌋)+Θ(n^2)
T(n)=3T(⌊n/4⌋)+Θ(n2)为例。为简化分析,我们将递归树中的
Θ
(
n
2
)
Θ(n^2)
Θ(n2)这一渐近符号项替换为一个代数式
c
n
2
cn^2
cn2。这里引入了第一个“不精确”因素,但是我们认为这不会影响最终结果。于是我们将递归树变为
T
(
n
)
=
3
T
(
⌊
n
/
4
⌋
)
+
c
n
2
T(n)=3T(⌊n/4⌋)+cn^2
T(n)=3T(⌊n/4⌋)+cn2。为方便起见,我们还假定
n
n
n是
4
4
4的幂。这里又引入了一个“不精确”因素,但我们同样认为这不会影响最终结果。现在可以创建递归树,如下图所示。
可以看到,递归树每下降一层,子问题规模减少为上一层的
1
/
4
1/4
1/4,因此深度为
i
i
i的结点,其子问题的规模为
n
/
4
i
n/4^i
n/4i。当到达叶结点时,子问题规模减为
1
1
1。假设叶结点深度为
k
k
k,那么有
n
/
4
k
=
1
n/4^k = 1
n/4k=1,得到
k
=
l
o
g
4
n
k={\rm log}_4n
k=log4n。所以叶结点深度为
l
o
g
4
n
{\rm log}_4n
log4n,这也说明整棵递归树的高度为
l
o
g
4
n
{\rm log}_4n
log4n。
现在统计递归树每一层的代价。对深度为
i
i
i的非叶结点来说,每一个结点对应一个规模为
n
/
4
i
n/4^i
n/4i的子问题,每个子问题产生代价
c
(
n
/
4
i
)
2
=
c
n
2
/
1
6
i
c(n/4^i)^2 = cn^2/16^i
c(n/4i)2=cn2/16i。从递归树可以看到,递归树每下降一层,结点数目变为上一层的
3
3
3倍,因此深度为
i
i
i的结点一共有
3
i
3^i
3i个。于是可以得到,除叶结点那一层外,深度为
i
i
i的那一层的结点代价之和为
3
i
•
(
c
n
2
/
1
6
i
)
=
(
3
/
16
)
i
c
n
2
3^i•(cn^2/16^i) = (3/16)^icn^2
3i•(cn2/16i)=(3/16)icn2。
现在考虑叶结点。一个叶结点对应规模为
1
1
1的子问题,它产生的代价为
T
(
1
)
T(1)
T(1)。通常来说,
T
(
1
)
T(1)
T(1)为常数时间,即
T
(
1
)
=
Θ
(
1
)
T(1) = Θ(1)
T(1)=Θ(1)。叶结点一共有
3
l
o
g
4
n
=
n
l
o
g
4
3
3^{{\rm log}_4n}=n^{{\rm log}_43}
3log4n=nlog43个,所以叶结点那一层的代价为
n
l
o
g
4
3
•
T
(
1
)
=
Θ
(
n
l
o
g
4
3
)
n^{{\rm log}_43}•T(1)=Θ(n^{{\rm log}_43})
nlog43•T(1)=Θ(nlog43)。
现在将递归树每一层代价加起来,得到递归树的总代价为
这样,对原始递归式
T
(
n
)
=
3
T
(
⌊
n
/
4
⌋
)
+
Θ
(
n
2
)
T(n)=3T(⌊n/4⌋)+Θ(n^2)
T(n)=3T(⌊n/4⌋)+Θ(n2),我们得到了一个猜测解
T
(
n
)
=
O
(
n
2
)
T(n)=O(n^2)
T(n)=O(n2)。由于根结点对总代价的贡献为
c
n
2
cn^2
cn2,所以根结点的代价支配了整棵递归树的总代价。
现在用代入法对猜测解进行验证。我们要证明的是:存在正常数
d
d
d,使得
T
(
n
)
≤
d
n
2
T(n) ≤ dn^2
T(n)≤dn2对足够大的
n
n
n都成立。将
T
(
n
)
≤
d
n
2
T(n) ≤ dn^2
T(n)≤dn2代入递归式得到
当
d
≥
16
13
c
d ≥ \frac{16}{13}c
d≥1316c时,不等式
3
16
d
n
2
+
c
n
2
≤
d
n
2
\frac{3}{16}dn^2+cn^2≤dn^2
163dn2+cn2≤dn2成立,此时
T
(
n
)
≤
d
n
2
T(n) ≤ dn^2
T(n)≤dn2成立。因此
T
(
n
)
=
O
(
n
2
)
T(n)=O(n^2)
T(n)=O(n2)得证。
现在考察一个更复杂的递归式
T
(
n
)
=
T
(
n
/
3
)
+
T
(
2
n
/
3
)
+
O
(
n
)
T(n)=T(n/3)+T(2n/3)+O(n)
T(n)=T(n/3)+T(2n/3)+O(n)。与之前一样,将渐近项
O
(
n
)
O(n)
O(n)替换为代数式
c
n
cn
cn,递归式变为
T
(
n
)
=
T
(
n
/
3
)
+
T
(
2
n
/
3
)
+
c
n
T(n)=T(n/3)+T(2n/3)+cn
T(n)=T(n/3)+T(2n/3)+cn。现在创建递归树,如下图所示。
由于每个结点的左右孩子的规模不一样,这意味着每个结点的左右子树的高度不一样,右子树比左子树要高,因此这棵树并不是一棵满二叉树。从根结点到叶结点的最长简单路径是
n
→
(
2
/
3
)
n
→
(
2
/
3
)
2
n
→
…
→
1
n → (2/3)n → (2/3)^2n → … → 1
n→(2/3)n→(2/3)2n→…→1。假设树的高度为
h
h
h,那么有
(
2
/
3
)
h
•
n
=
1
(2/3)^h•n = 1
(2/3)h•n=1,得到
h
=
l
o
g
3
/
2
n
h={\rm log}_{3/2}n
h=log3/2n。
在上图中,我们只画出了递归树的顶部几层,可以看到每层的代价都为
c
n
cn
cn。然而由于递归树并不是一棵满二叉树,所以并不是每层的代价都为
c
n
cn
cn。随着递归树的层级越往下降,缺失的结点会越来多,这些存在缺失结点的层级的代价小于
c
n
cn
cn。只有递归树靠顶部的那些不存在缺失结点的层级,它们的代价等于
c
n
cn
cn。由于我们只需要通过递归树获得一个猜测解,所以我们不考虑这些缺失结点的影响,于是我们猜测解为
T
(
n
)
=
O
(
c
n
•
l
o
g
3
/
2
n
)
=
O
(
n
l
g
n
)
T(n)=O(cn•{\rm log}_{3/2}n)=O(n{\rm lg}n)
T(n)=O(cn•log3/2n)=O(nlgn)。注意,这里又引入了另一种形式的“不精确”因素。
现在用代入法对猜测解进行验证。我们要证明的是:存在正常数
d
d
d,使得
T
(
n
)
≤
d
n
l
g
n
T(n) ≤ dn{\rm lg}n
T(n)≤dnlgn对足够大的
n
n
n都成立。将
T
(
n
)
≤
d
n
l
g
n
T(n) ≤ dn{\rm lg}n
T(n)≤dnlgn代入递归式得到
只要取
d
≥
c
l
g
3
−
2
/
3
d≥\frac{c}{{\rm lg}3-2/3}
d≥lg3−2/3c,就能使得不等式
d
n
l
g
n
−
d
n
(
l
g
3
−
2
3
)
+
c
n
≤
d
n
l
g
n
dn{\rm lg}n-dn({\rm lg}3-\frac{2}{3})+cn≤dn{\rm lg}n
dnlgn−dn(lg3−32)+cn≤dnlgn成立,此时
T
(
n
)
≤
d
n
l
g
n
T(n)≤dn{\rm lg}n
T(n)≤dnlgn成立。因此
T
(
n
)
=
O
(
n
l
g
n
)
T(n)=O(n{\rm lg}n)
T(n)=O(nlgn)得证。
练习
4.4-1 对递归式
T
(
n
)
=
3
T
(
⌊
n
/
2
⌋
)
+
n
T(n)=3T(⌊n/2⌋)+n
T(n)=3T(⌊n/2⌋)+n,利用递归树确定一个好的渐近上界,用代入法进行验证。
解
创建递归树,如下图所示。
在递归树中,深度为
i
i
i的结点对应规模为
n
/
2
i
n/2^i
n/2i的子问题。当
n
/
2
i
=
1
n/2^i = 1
n/2i=1时,即
i
=
l
g
n
i = {\rm lg}n
i=lgn时,子问题规模变为
1
1
1,这对应于叶结点
T
(
1
)
T(1)
T(1),因此树的高度
h
=
l
g
n
h = {\rm lg}n
h=lgn。
每层的结点数都是上一层的
3
3
3倍,因此深度为
i
i
i的结点数为
3
i
3^i
3i。深度为
i
i
i的结点对应的子问题规模为
n
/
2
i
n/2^i
n/2i,除叶结点外,深度为
i
i
i的每个结点的代价为
n
/
2
i
n/2^i
n/2i。因此,除叶结点外,深度为
i
i
i的所有结点的代价为
3
i
•
(
n
/
2
i
)
=
(
3
/
2
)
i
n
3^i•(n/2^i )=(3/2)^in
3i•(n/2i)=(3/2)in。叶结点一共有
3
l
g
n
=
n
l
g
3
3^{{\rm lg}n}=n^{{\rm lg}3}
3lgn=nlg3个,所以叶结点那一层的代价为
Θ
(
n
l
g
3
)
Θ(n^{{\rm lg}3})
Θ(nlg3)。
现在将每一层的代价加起来,得到
下面用代入法验证这一结果。在做归纳假设时,需要减去一个低阶项,才能顺利完成证明。于是我们要证明的是:存在正常数
c
c
c和
d
d
d,使得
T
(
n
)
≤
c
n
l
g
3
−
d
n
T(n)≤cn^{{\rm lg}3}-dn
T(n)≤cnlg3−dn对足够大的n都成立。
取初始情况
T
(
1
)
=
1
T(1) = 1
T(1)=1。只要取
c
≥
d
+
1
c ≥ d + 1
c≥d+1,就能使得
T
(
1
)
≤
c
•
1
l
g
3
−
d
•
1
=
c
−
d
T(1) ≤ c•1^{{\rm lg}3} − d•1 = c − d
T(1)≤c•1lg3−d•1=c−d成立。
现在考虑
n
≥
2
n ≥ 2
n≥2的情况。假设
T
(
n
)
≤
c
n
l
g
3
−
d
n
T(n)≤cn^{{\rm lg}3}-dn
T(n)≤cnlg3−dn对
1
,
2
,
…
,
n
−
1
1, 2, …, n−1
1,2,…,n−1都成立,于是有
T
(
n
)
=
3
T
(
⌊
n
/
2
⌋
)
+
n
≤
3
c
(
n
2
)
l
g
3
−
3
d
•
n
2
+
n
=
c
n
l
g
3
−
(
3
2
d
−
1
)
n
T(n)=3T(⌊n/2⌋)+n≤3c(\frac{n}{2})^{{\rm lg}3}-3d•\frac{n}{2}+n=cn^{{\rm lg}3}-(\frac{3}{2}d-1)n
T(n)=3T(⌊n/2⌋)+n≤3c(2n)lg3−3d•2n+n=cnlg3−(23d−1)n
现在要选取合适的
c
c
c和
d
d
d,使得不等式
c
n
l
g
3
−
(
3
2
d
−
1
)
n
≤
c
n
l
g
3
−
d
n
cn^{{\rm lg}3}-(\frac{3}{2}d-1)n≤cn^{{\rm lg}3}-dn
cnlg3−(23d−1)n≤cnlg3−dn成立。对该不等式做一下变换。
c
n
l
g
3
−
(
3
2
d
−
1
)
n
≤
c
n
l
g
3
−
d
n
cn^{{\rm lg}3}-(\frac{3}{2}d-1)n≤cn^{{\rm lg}3}-dn
cnlg3−(23d−1)n≤cnlg3−dn ⇔
(
3
2
d
−
1
)
n
≥
d
n
(\frac{3}{2}d-1)n≥dn
(23d−1)n≥dn ⇔
d
≥
2
d≥2
d≥2
因此,只要取
d
≥
2
d ≥ 2
d≥2,并且
c
c
c取任意值,就能使能不等式
c
n
l
g
3
−
(
3
2
d
−
1
)
n
≤
c
n
l
g
3
−
d
n
cn^{{\rm lg}3}-(\frac{3}{2}d-1)n≤cn^{{\rm lg}3}-dn
cnlg3−(23d−1)n≤cnlg3−dn成立,此时
T
(
n
)
≤
c
n
l
g
3
−
d
n
T(n)≤cn^{{\rm lg}3}-dn
T(n)≤cnlg3−dn成立。
综合考虑初始情况
T
(
1
)
T(1)
T(1),我们最终要取
d
≥
2
d ≥ 2
d≥2并且
c
≥
d
+
1
c ≥ d + 1
c≥d+1。于是
T
(
n
)
=
O
(
n
l
g
3
)
T(n)=O(n^{{\rm lg}3})
T(n)=O(nlg3)得证。
4.4-2 对递归式
T
(
n
)
=
T
(
n
/
2
)
+
n
2
T(n)=T(n/2)+n^2
T(n)=T(n/2)+n2,利用递归树确定一个好的渐近上界,用代入法进行验证。
解
创建递归树,如下图所示。
在递归树中,深度为
i
i
i的结点对应规模为
n
/
2
i
n/2^i
n/2i的子问题。当
n
/
2
i
=
1
n/2^i = 1
n/2i=1时,即
i
=
l
g
n
i = {\rm lg}n
i=lgn时,子问题规模变为
1
1
1,这对应于叶结点
T
(
1
)
T(1)
T(1),因此树的高度
h
=
l
g
n
h = {\rm lg}n
h=lgn。
每层只有一个结点。除叶结点外,深度为
i
i
i的结点的代价为
(
n
/
2
i
)
2
=
n
2
/
4
i
(n/2^i)^2 = n^2/4^i
(n/2i)2=n2/4i。叶结点的代价为
T
(
1
)
=
Θ
(
1
)
T(1) = Θ(1)
T(1)=Θ(1)。现在将每一层的代价加起来,得到
用代入法验证这一结果比较简单,这里省略具体过程。
4.4-3 对递归式
T
(
n
)
=
4
T
(
n
/
2
+
2
)
+
n
T(n)=4T(n/2+2)+n
T(n)=4T(n/2+2)+n,利用递归树确定一个好的渐近上界,用代入法进行验证。
解
直接对递归式
T
(
n
)
=
4
T
(
n
/
2
+
2
)
+
n
T(n)=4T(n/2+2)+n
T(n)=4T(n/2+2)+n创建递归树很困难。将递归式变换为
T
(
n
)
=
4
T
(
n
/
2
)
+
n
T(n)=4T(n/2)+n
T(n)=4T(n/2)+n,因为当
n
n
n足够大时
n
/
2
+
2
n/2+2
n/2+2和
n
/
2
n/2
n/2很接近,我们预计这样做不会影响最终结果。现在创建递归树,如下图所示。
在递归树中,深度为
i
i
i的结点对应规模为
n
/
2
i
n/2^i
n/2i的子问题。当
n
/
2
i
=
1
n/2^i = 1
n/2i=1时,即
i
=
l
g
n
i = {\rm lg}n
i=lgn时,子问题规模变为
1
1
1,这对应于叶结点
T
(
1
)
T(1)
T(1),因此树的高度
h
=
l
g
n
h = {\rm lg}n
h=lgn。
每层的结点数都是上一层的
4
4
4倍,因此深度为
i
i
i的结点数为
4
i
4^i
4i。深度为
i
i
i的结点对应的子问题规模为
n
/
2
i
n/2^i
n/2i,除叶结点外,深度为
i
i
i的每个结点的代价为
n
/
2
i
n/2^i
n/2i。因此,除叶结点外,深度为
i
i
i的所有结点的代价为
4
i
•
(
n
/
2
i
)
=
2
i
•
n
4^i•(n/2^i)=2^i•n
4i•(n/2i)=2i•n。叶结点一共有
4
l
g
n
=
n
2
4^{{\rm lg}n}=n^2
4lgn=n2个,所以叶结点那一层的代价为
Θ
(
n
2
)
Θ(n^2)
Θ(n2)。
现在将每一层的代价加起来,得到
下面用代入法验证这一结果。我们没有办法直接证明
T
(
n
)
≤
c
n
2
T(n)≤cn^2
T(n)≤cn2,不妨证明:存在正常数
c
c
c和
d
d
d,使得
T
(
n
)
≤
c
(
n
−
4
)
2
−
d
(
n
−
4
)
T(n)≤c(n-4)^2-d(n-4)
T(n)≤c(n−4)2−d(n−4)对足够大的
n
n
n都成立。
要使原递归式
T
(
n
)
=
4
T
(
n
/
2
+
2
)
+
n
T(n)=4T(n/2+2)+n
T(n)=4T(n/2+2)+n有意义,必须有
n
>
n
/
2
+
2
n > n/2 + 2
n>n/2+2,得到
n
>
4
n > 4
n>4,即
n
≥
5
n ≥ 5
n≥5。所以取初始情况
T
(
5
)
=
1
T(5) = 1
T(5)=1。只要取
c
≥
d
+
1
c ≥ d + 1
c≥d+1,就能使得
T
(
5
)
≤
c
•
(
5
−
4
)
2
−
d
•
(
5
−
4
)
=
c
−
d
T(5) ≤ c•(5−4)^2 − d•(5−4) = c − d
T(5)≤c•(5−4)2−d•(5−4)=c−d成立。
现在考虑
n
≥
6
n ≥ 6
n≥6的情况。假设
T
(
n
)
≤
c
(
n
−
4
)
2
−
d
(
n
−
4
)
T(n)≤c(n-4)^2-d(n-4)
T(n)≤c(n−4)2−d(n−4)对
5
,
6
,
…
,
n
−
1
5, 6, …, n−1
5,6,…,n−1都成立,于是有
现在要选取合适的
c
c
c和
d
d
d,使得不等式
c
(
n
−
4
)
2
−
d
(
2
n
−
8
)
+
n
≤
c
(
n
−
4
)
2
−
d
(
n
−
4
)
c(n-4)^2-d(2n-8)+n≤c(n-4)^2-d(n-4)
c(n−4)2−d(2n−8)+n≤c(n−4)2−d(n−4)成立。对这个不等式做一下变换。
当
n
≥
6
n ≥ 6
n≥6时,
1
/
(
1
−
4
/
n
)
1/(1-4/n)
1/(1−4/n)是单调递减的,并且在
n
=
6
n = 6
n=6时取得最大值为
3
3
3。因此,只要取
d
≥
3
d ≥ 3
d≥3,就能使得不等式
c
(
n
−
4
)
2
−
d
(
2
n
−
8
)
+
n
≤
c
(
n
−
4
)
2
−
d
(
n
−
4
)
c(n-4)^2-d(2n-8)+n≤c(n-4)^2-d(n-4)
c(n−4)2−d(2n−8)+n≤c(n−4)2−d(n−4)成立,此时
T
(
n
)
≤
c
(
n
−
4
)
2
−
d
(
n
−
4
)
T(n)≤c(n-4)^2-d(n-4)
T(n)≤c(n−4)2−d(n−4)成立。
综合考虑初始情况
T
(
5
)
T(5)
T(5),我们最终要取
d
≥
3
d ≥ 3
d≥3并且
c
≥
d
+
1
c ≥ d + 1
c≥d+1。于是
T
(
n
)
=
O
(
n
2
)
T(n)=O(n^2)
T(n)=O(n2)得证。
4.4-4 对递归式
T
(
n
)
=
2
T
(
n
−
1
)
+
1
T(n)=2T(n-1)+1
T(n)=2T(n−1)+1,利用递归树确定一个好的渐近上界,用代入法进行验证。
解
创建递归树,如下图所示。
在递归树中,深度为
i
i
i的结点对应规模为
n
−
i
n − i
n−i的子问题。当
n
−
i
=
1
n − i = 1
n−i=1时,即
i
=
n
−
1
i = n − 1
i=n−1时,子问题规模变为
1
1
1,这对应于叶结点
T
(
1
)
T(1)
T(1),因此树的高度
h
=
n
−
1
h = n − 1
h=n−1。
每层的结点数都是上一层的
2
2
2倍,因此深度为
i
i
i的结点数为
2
i
2^i
2i。除叶结点外,每个结点的代价都为
1
1
1。因此,除叶结点外,深度为i的所有结点的代价为
2
i
•
1
=
2
i
2^i•1=2^i
2i•1=2i。叶结点一共有
2
n
−
1
2^{n-1}
2n−1个,所以叶结点那一层的代价为
Θ
(
2
n
)
Θ(2^n)
Θ(2n)。
现在将每一层的代价加起来,得到
下面用代入法验证这一结果。在做归纳假设时,需要减去一个低阶项,才能顺利完成证明。我们要证明的是:存在正常数
c
c
c和
d
d
d,使得
T
(
n
)
≤
c
•
2
n
−
d
T(n)≤c•2^n-d
T(n)≤c•2n−d对足够大的
n
n
n都成立。
取初始情况
T
(
1
)
=
1
T(1) = 1
T(1)=1。只要取
c
≥
(
d
+
1
)
/
2
c ≥ (d+1)/2
c≥(d+1)/2,就能使得
T
(
1
)
≤
c
•
2
1
–
d
=
2
c
–
d
T(1) ≤ c•2^1 – d = 2c – d
T(1)≤c•21–d=2c–d成立。
现在考虑
n
≥
2
n ≥ 2
n≥2的情况。假设
T
(
n
)
≤
c
•
2
n
−
d
T(n)≤c•2^n-d
T(n)≤c•2n−d对
1
,
2
,
…
,
n
−
1
1, 2, …, n−1
1,2,…,n−1都成立,于是有
T
(
n
)
=
2
T
(
n
−
1
)
+
1
≤
2
c
•
2
n
−
1
−
2
d
+
1
=
c
•
2
n
−
2
d
+
1
T(n)=2T(n-1)+1≤2c•2^{n-1}-2d+1=c•2^n-2d+1
T(n)=2T(n−1)+1≤2c•2n−1−2d+1=c•2n−2d+1
只要取
d
≥
1
d ≥ 1
d≥1,就能使得
c
•
2
n
−
2
d
+
1
≤
c
•
2
n
−
d
c•2^n-2d+1≤c•2^n-d
c•2n−2d+1≤c•2n−d成立,此时
T
(
n
)
≤
c
•
2
n
−
d
T(n)≤c•2^n-d
T(n)≤c•2n−d成立。
综合考虑初始情况
T
(
1
)
T(1)
T(1),我们最终要取
d
≥
1
d ≥ 1
d≥1并且
c
≥
(
d
+
1
)
/
2
c ≥ (d+1)/2
c≥(d+1)/2。于是
T
(
n
)
=
O
(
2
n
)
T(n)=O(2^n)
T(n)=O(2n)得证。
4.4-5 对递归式
T
(
n
)
=
T
(
n
−
1
)
+
T
(
n
/
2
)
+
n
T(n)=T(n-1)+T(n/2)+n
T(n)=T(n−1)+T(n/2)+n,利用递归树确定一个好的渐近上界,用代入法进行验证。
解
创建递归树,如下图所示。
该递归树显然不是一棵满二叉树。从根结点到叶结点的最短简单路径是
n
→
n
/
2
→
n
/
4
→
…
→
1
n → n/2 → n/4 → … → 1
n→n/2→n/4→…→1。假设这一最短简单路径上叶结点深度为
k
k
k,那么有
(
1
/
2
)
k
•
n
=
1
(1/2)k•n = 1
(1/2)k•n=1,得到
k
=
l
g
n
k={\rm lg}n
k=lgn。从根结点到叶结点的最短简单路径是
n
→
n
−
1
→
n
−
2
→
…
→
1
n → n−1 → n−2 → … → 1
n→n−1→n−2→…→1。假设这一最短简单路径上叶结点深度为
l
l
l,那么有
n
−
l
=
1
n − l = 1
n−l=1,得到
l
=
n
−
1
l=n-1
l=n−1。
从递归树可以看到,第i层的代价为
(
3
/
2
)
i
•
n
–
e
(3/2)^i•n – e
(3/2)i•n–e,其中
e
e
e为低阶项。我们要确定
T
(
n
)
T(n)
T(n)的渐近上界,为方便起见,忽略每一层代价中的低阶项
e
e
e,统计第
0
0
0层到第
n
−
1
n − 1
n−1层的代价之和,得到
当
n
n
n足够大时,有
2
•
(
3
/
2
)
n
•
n
<
2
n
2•(3/2)^n•n<2^n
2•(3/2)n•n<2n,因此得到
T
(
n
)
=
O
(
2
n
)
T(n) = O(2^n)
T(n)=O(2n)。
下面用代入法验证这一结果。在做归纳假设时,需要减去一个低阶项,才能顺利完成证明。我们要证明的是:存在正常数
c
c
c和
d
d
d,使得
T
(
n
)
≤
c
•
2
n
−
d
n
T(n)≤c•2^n-dn
T(n)≤c•2n−dn对足够大的n都成立。
取初始情况
T
(
1
)
=
1
T(1) = 1
T(1)=1。只要取
c
≥
(
d
+
1
)
/
2
c ≥ (d+1)/2
c≥(d+1)/2,就能使得
T
(
1
)
≤
c
•
2
1
–
d
•
1
=
2
c
–
d
T(1) ≤ c•2^1 – d•1 = 2c – d
T(1)≤c•21–d•1=2c–d成立。
现在考虑
n
≥
2
n ≥ 2
n≥2的情况。假设
T
(
n
)
≤
c
•
2
n
−
d
n
T(n)≤c•2^n-dn
T(n)≤c•2n−dn对
1
,
2
,
…
,
n
−
1
1, 2, …, n−1
1,2,…,n−1都成立,于是有
现在要选取合适的
c
c
c和
d
d
d,使得不等式
c
•
2
n
−
(
3
d
2
−
1
)
n
≤
c
•
2
n
−
d
n
c•2^n-(\frac{3d}{2}-1)n≤c•2^n-dn
c•2n−(23d−1)n≤c•2n−dn成立。对该不等式做一下变换。
显然,只要取
d
≥
2
d ≥ 2
d≥2,就能使得
c
•
2
n
−
(
3
d
2
−
1
)
n
≤
c
•
2
n
−
d
n
c•2^n-(\frac{3d}{2}-1)n≤c•2^n-dn
c•2n−(23d−1)n≤c•2n−dn成立,此时
T
(
n
)
≤
c
•
2
n
−
d
n
T(n)≤c•2^n-dn
T(n)≤c•2n−dn成立。
综合考虑初始情况
T
(
1
)
T(1)
T(1),我们最终要取
d
≥
2
d ≥ 2
d≥2并且
c
≥
(
d
+
1
)
/
2
c ≥ (d+1)/2
c≥(d+1)/2。于是
T
(
n
)
=
O
(
2
n
)
T(n)=O(2^n)
T(n)=O(2n)得证。
4.4-6 对递归式
T
(
n
)
=
T
(
n
/
3
)
+
T
(
2
n
/
3
)
+
c
n
T(n)=T(n/3)+T(2n/3)+cn
T(n)=T(n/3)+T(2n/3)+cn,利用递归树论证其解为
Ω
(
n
l
g
n
)
Ω(n{\rm lg}n)
Ω(nlgn),其中
c
c
c为常数。
解
创建递归树,如下图所示。
由于每个结点的左右孩子的规模不一样,这意味着每个结的左右子树的高度不一样,右子树比左子树要高,因此这棵树并不是一棵满二叉树。从根结点到叶结点的最短简单路径是
n
→
(
1
/
3
)
n
→
(
1
/
3
)
2
n
→
…
→
1
n → (1/3)n → (1/3)^2n → … → 1
n→(1/3)n→(1/3)2n→…→1。假设这一最短简单路径上叶结点深度为
k
k
k,那么有
(
1
/
3
)
k
•
n
=
1
(1/3)^k•n = 1
(1/3)k•n=1,得到
k
=
l
o
g
3
n
k={\rm log}_3n
k=log3n。这意味着递归树中第
l
o
g
3
n
{\rm log}_3n
log3n层及以上的层级都是满的,这些层级的每一层的代价都为
c
n
cn
cn。
我们求的是
T
(
n
)
T(n)
T(n)的渐近下界,因此可以只统计递归树中第
l
o
g
3
n
{\rm log}_3n
log3n层及以上的层级的代价。于是得到
用代入法验证这一结果比较简单,这里省略具体过程。
4.4-7 对递归式
T
(
n
)
=
4
T
(
⌊
n
/
2
⌋
)
+
c
n
T(n)=4T(⌊n/2⌋)+cn
T(n)=4T(⌊n/2⌋)+cn(
c
c
c为常数),画出递归树,并给出其解的一个渐近紧确界。用代入法进行验证。
解
本题的递归树与练习4.4-3的递归树几乎一样,如下图所示。
将每一层的代价加起来,得到
下面用代入法验证这一结果。在做归纳假设时,需要减去一个低阶项,才能顺利完成证明。于是我们要证明的是:存在正常数
d
1
d_1
d1、
d
2
d_2
d2和
e
e
e,使得
d
1
(
n
2
−
e
n
)
≤
T
(
n
)
≤
d
2
(
n
2
−
e
n
)
d_1(n^2-en)≤T(n)≤d_2(n^2-en)
d1(n2−en)≤T(n)≤d2(n2−en)对足够大的
n
n
n都成立。需要分两步证明。
(1) 证明存在正常数
d
1
d_1
d1和
e
e
e,使得
T
(
n
)
≥
d
1
(
n
2
−
e
n
)
T(n)≥d_1(n^2-en)
T(n)≥d1(n2−en)对足够大的n都成立
取初始情况
T
(
1
)
=
1
T(1) = 1
T(1)=1。只要取
d
1
≤
1
/
(
1
−
e
)
d_1 ≤ 1/(1−e)
d1≤1/(1−e)并且
e
<
1
e < 1
e<1,就能使得
T
(
1
)
≥
d
1
(
1
2
−
e
•
1
)
=
d
1
(
1
−
e
)
T(1) ≥ d_1(1^2 − e•1) = d_1(1 − e)
T(1)≥d1(12−e•1)=d1(1−e)成立。
现在考虑
n
≥
2
n ≥ 2
n≥2的情况。假设
T
(
n
)
≥
d
1
(
n
2
−
e
n
)
T(n)≥d_1(n^2-en)
T(n)≥d1(n2−en)对
1
,
2
,
…
,
n
−
1
1, 2, …, n−1
1,2,…,n−1都成立,于是有
现在要选取合适的
d
1
d_1
d1和
e
e
e,使得不等式
d
1
(
n
2
−
2
n
+
1
−
2
e
n
)
+
c
n
≥
d
1
(
n
2
−
e
n
)
d_1(n^2-2n+1-2en)+cn≥d_1(n^2-en)
d1(n2−2n+1−2en)+cn≥d1(n2−en)成立。对该不等式做一下变换。
当
n
≥
2
n ≥ 2
n≥2时,
c
(
e
+
2
)
−
1
/
n
\frac{c}{(e+2)-1/n}
(e+2)−1/nc是单调递减的,并且在
n
=
∞
n = ∞
n=∞时取得最小值为
c
e
+
2
\frac{c}{e+2}
e+2c。因此,只要取
d
1
≤
c
e
+
2
d_1 ≤ \frac{c}{e+2}
d1≤e+2c,就能使得不等式
d
1
(
n
2
−
2
n
+
1
−
2
e
n
)
+
c
n
≥
d
1
(
n
2
−
e
n
)
d_1(n^2-2n+1-2en)+cn≥d_1(n^2-en)
d1(n2−2n+1−2en)+cn≥d1(n2−en)成立,此时
T
(
n
)
≥
d
1
(
n
2
−
e
n
)
T(n)≥d_1(n^2-en)
T(n)≥d1(n2−en)成立。
综合考虑初始情况
T
(
1
)
T(1)
T(1),我们最终要取
e
<
1
e < 1
e<1并且
d
1
≤
m
i
n
{
1
1
−
e
,
c
e
+
2
}
d_1 ≤ min\{\frac{1}{1−e}, \frac{c}{e+2}\}
d1≤min{1−e1,e+2c}。于是
T
(
n
)
≥
d
1
(
n
2
−
e
n
)
T(n)≥d_1(n^2-en)
T(n)≥d1(n2−en)得证。
(2) 证明存在正常数
d
2
d_2
d2和
e
e
e,使得
T
(
n
)
≤
d
2
(
n
2
−
e
n
)
T(n)≤d_2(n^2-en)
T(n)≤d2(n2−en)对足够大的
n
n
n都成立
取初始情况
T
(
1
)
=
1
T(1) = 1
T(1)=1。只要取
d
2
≥
1
/
(
1
−
e
)
d_2 ≥ 1/(1−e)
d2≥1/(1−e)并且
e
<
1
e < 1
e<1,就能使得
T
(
1
)
≤
d
2
(
1
2
−
e
•
1
)
=
d
2
(
1
−
e
)
T(1) ≤ d_2(1^2 − e•1) = d_2(1 − e)
T(1)≤d2(12−e•1)=d2(1−e)成立。
现在考虑
n
≥
2
n ≥ 2
n≥2的情况。假设
T
(
n
)
≤
d
2
(
n
2
−
e
n
)
T(n)≤d_2(n^2-en)
T(n)≤d2(n2−en)对
1
,
2
,
…
,
n
−
1
1, 2, …, n−1
1,2,…,n−1都成立,于是有
现在要选取合适的
d
2
d_2
d2和
e
e
e,使得不等式
d
2
(
n
2
−
2
e
n
)
+
c
n
≤
d
2
(
n
2
−
e
n
)
d_2(n^2-2en)+cn≤d_2(n^2-en)
d2(n2−2en)+cn≤d2(n2−en)成立。对该不等式做一下变换。
因此,只要取
d
2
≥
c
/
e
d_2 ≥ c/e
d2≥c/e,就能使能不等式
d
2
(
n
2
−
2
e
n
)
+
c
n
≤
d
2
(
n
2
−
e
n
)
d_2(n^2-2en)+cn≤d_2(n^2-en)
d2(n2−2en)+cn≤d2(n2−en)成立,此时
T
(
n
)
≤
d
2
(
n
2
−
e
n
)
T(n)≤d_2(n^2-en)
T(n)≤d2(n2−en)成立。
综合考虑初始情况
T
(
1
)
T(1)
T(1),我们最终要取
e
<
1
e < 1
e<1并且
d
2
≤
m
a
x
{
1
1
−
e
,
c
e
}
d_2 ≤ max\{\frac{1}{1−e}, \frac{c}{e}\}
d2≤max{1−e1,ec}。于是
T
(
n
)
≤
d
2
(
n
2
−
e
n
)
T(n)≤d_2(n^2-en)
T(n)≤d2(n2−en)得证。
综合(1)和(2),只要取
e
<
1
e < 1
e<1、
d
1
≤
m
i
n
{
1
1
−
e
,
c
e
+
2
}
d_1 ≤ min\{\frac{1}{1−e}, \frac{c}{e+2}\}
d1≤min{1−e1,e+2c}并且
d
2
≤
m
a
x
{
1
1
−
e
,
c
e
}
d_2 ≤ max\{\frac{1}{1−e}, \frac{c}{e}\}
d2≤max{1−e1,ec},就能使得
d
1
(
n
2
−
e
n
)
≤
T
(
n
)
≤
d
2
(
n
2
−
e
n
)
d_1(n^2-en)≤T(n)≤d_2(n^2-en)
d1(n2−en)≤T(n)≤d2(n2−en)成立。因此,
T
(
n
)
=
Θ
(
n
2
)
T(n)=Θ(n^2)
T(n)=Θ(n2)得证。
4.4-8 对递归式
T
(
n
)
=
T
(
n
−
a
)
+
T
(
a
)
+
c
n
T(n)=T(n-a)+T(a)+cn
T(n)=T(n−a)+T(a)+cn,利用递归树给出一个渐近紧确解,其中
a
≥
1
a ≥ 1
a≥1和
c
>
0
c > 0
c>0是常数。
解
创建递归树,如下图所示。
在递归树中,每个结点均有
2
2
2个孩子,其中右孩子都为
T
(
a
)
T(a)
T(a)。所以除根结点外,每一层都只有
2
2
2个结点。深度为
i
i
i的结点其中一个对应规模为
n
−
a
i
n−ai
n−ai的子问题,另一个对应规模为
a
a
a的子问题。当
n
−
a
i
=
a
n − ai = a
n−ai=a时,即
i
=
(
n
/
a
)
−
1
i = (n/a) − 1
i=(n/a)−1时,子问题规模变为
a
a
a,这对应于最底层的叶结点
T
(
a
)
T(a)
T(a),因此树的高度
h
=
(
n
/
a
)
−
1
h = (n/a) − 1
h=(n/a)−1。
除叶结点外,深度为
i
i
i的结点其中一个对应规模为
n
−
a
i
n−ai
n−ai的子问题,它的代价为
c
(
n
−
a
i
)
c(n−ai)
c(n−ai);另一个对应规模为
a
a
a的子问题,它的代价为
T
(
a
)
T(a)
T(a)。因此,除叶结点外,深度为
i
i
i的所有结点的代价为
c
(
n
−
a
i
)
+
T
(
a
)
c(n−ai) + T(a)
c(n−ai)+T(a)。叶结点一共有
2
2
2个,所以叶结点那一层的代价为
2
T
(
a
)
2T(a)
2T(a)。
现在将每一层的代价加起来,得到
4.4-9 对递归式
T
(
n
)
=
T
(
α
n
)
+
T
(
(
1
−
α
)
n
)
+
c
n
T(n)=T(αn)+T((1-α)n)+cn
T(n)=T(αn)+T((1−α)n)+cn,利用递归树给出一个渐近紧确解,其中
0
<
α
<
1
0 < α < 1
0<α<1和
c
>
0
c > 0
c>0是常数。
解
创建递归树,如下图所示。
为方便起见,假设
0
<
α
≤
1
/
2
0 < α ≤ 1/2
0<α≤1/2。
1
/
2
<
α
<
1
1/2 < α < 1
1/2<α<1是对称的情况。从根结点到叶结点的最短简单路径是
n
→
α
n
→
α
2
n
→
…
→
1
n → αn → α2n → … → 1
n→αn→α2n→…→1。假设这一最短简单路径上叶结点深度为
k
k
k,那么有
α
k
•
n
=
1
α^k•n = 1
αk•n=1,得到
k
=
l
o
g
1
/
α
n
k={\rm log}_{1/α}n
k=log1/αn。从根结点到叶结点的最短简单路径是
n
→
(
1
−
α
)
n
→
(
1
−
α
)
2
n
→
…
→
1
n → (1−α)n → (1−α)2n → … → 1
n→(1−α)n→(1−α)2n→…→1。假设这一最短简单路径上叶结点深度为
l
l
l,那么有
(
1
−
α
)
l
•
n
=
1
(1−α)^l•n = 1
(1−α)l•n=1,得到
l
=
l
o
g
1
/
(
1
−
α
)
n
l={\rm log}_{1/(1-α)} n
l=log1/(1−α)n。
上图画出了递归树的顶部几层,顶部几层的代价都等于
c
n
cn
cn,严格来说,从根结点到第
l
o
g
1
/
α
n
{\rm log}_{1/α}n
log1/αn层,每一层的代价都为
c
n
cn
cn。只统计根结点到第
l
o
g
1
/
α
n
{\rm log}_{1/α}n
log1/αn层的代价,就可以得到
T
(
n
)
T(n)
T(n)的下界,于是有
随着递归树层级往下降,缺失的内部结点越来越多,因此底部几层的代价都不超过
c
n
cn
cn。于是有
综合以上分析,得到
T
(
n
)
=
Θ
(
n
l
g
n
)
T(n) = Θ(n{\rm lg}n)
T(n)=Θ(nlgn)。