递归算法的复杂度
文字和代码来源:《数据结构与算法python语言描述》裘宗燕
推导过程为原创,应该有不够严谨之处,欢迎指出
递归算法通常具有如下的算法模式
def recur(n):
if n == 0:
return g(...)
somework
for i in range(a):
x = recur(n/b)
somework
somework
也就是说,n值为0时直接得到结果,否则将原问题归结为a个规模为n/b的子问题,其中a和b是由具体问题决定的两个常量。另外,在本层递归中还需要一些工作,上面描述里用somework表示,其时间复杂度可能与n有关,设为
O
(
n
k
)
O(n^{k})
O(nk)。这个k也应该是常量,k=0表示这部分工作与n无关。
得到递归方程如下:
T
(
n
)
=
O
(
n
k
)
+
a
×
T
(
n
/
b
)
=
O
(
n
k
)
+
a
×
(
O
(
n
/
b
)
k
+
a
×
T
(
n
/
b
)
)
=
.
.
.
=
O
(
n
k
)
+
a
×
O
(
n
/
b
)
k
+
a
2
×
O
(
n
/
b
2
)
k
+
.
.
.
+
a
(
l
o
g
b
n
)
−
1
×
O
(
(
n
/
b
(
l
o
g
b
n
)
−
1
)
k
)
+
a
l
o
g
b
n
×
T
(
1
)
T(n) = O(n^{k})+a×T(n/b)=O(n^{k})+a×(O(n/b)^{k}+a×T(n/b))=... =O(n^{k})+a×O(n/b)^{k}+a^{2}×O(n/b^{2})^{k}+...+a^{(log_bn) - 1}×O((n/b^{(log_bn) - 1})^{k})+a^{log_bn}×T(1)
T(n)=O(nk)+a×T(n/b)=O(nk)+a×(O(n/b)k+a×T(n/b))=...=O(nk)+a×O(n/b)k+a2×O(n/b2)k+...+a(logbn)−1×O((n/b(logbn)−1)k)+alogbn×T(1)
这里面
T
(
1
)
=
O
(
1
)
,
a
l
o
g
b
n
=
a
l
o
g
a
n
/
l
o
g
a
b
=
n
l
o
g
a
b
T(1)=O(1),a^{log_bn}=a^{log_an/log_ab}=n^{log_ab}
T(1)=O(1),alogbn=alogan/logab=nlogab,注意到a,b,k都是常数
所以有
T
(
n
)
=
O
(
n
k
)
+
a
×
O
(
n
/
b
)
k
+
a
2
×
O
(
n
/
b
2
)
k
+
.
.
.
+
a
(
l
o
g
b
n
)
−
1
×
O
(
b
k
)
+
O
(
n
l
o
g
a
b
)
T(n) = O(n^{k})+a×O(n/b)^{k}+a^{2}×O(n/b^{2})^{k}+...+a^{(log_bn) - 1}×O(b^{k})+O(n^{log_ab})
T(n)=O(nk)+a×O(n/b)k+a2×O(n/b2)k+...+a(logbn)−1×O(bk)+O(nlogab)
根据加法原则
当
a
>
b
k
,
即
k
<
l
o
g
b
a
时
a>b^{k},即k<log_ba时
a>bk,即k<logba时
a
>
b
k
,
T
(
n
)
=
O
(
n
l
o
g
b
a
)
a>b^{k},T(n)=O(n^{log_ba})
a>bk,T(n)=O(nlogba)
当
a
=
b
k
,
即
k
=
l
o
g
b
a
时
a=b^{k},即k=log_ba时
a=bk,即k=logba时
总共有
(
l
o
g
b
n
+
1
)
个
O
(
n
k
)
(log_bn+1)个O(n^{k})
(logbn+1)个O(nk),忽略常数造成的影响
a
=
b
k
,
T
(
n
)
=
O
(
n
k
l
o
g
2
n
)
a=b^{k},T(n)=O(n^{k}log_2n)
a=bk,T(n)=O(nklog2n)
当
a
<
b
k
,
即
k
>
l
o
g
b
a
时
a<b^{k},即k>log_ba时
a<bk,即k>logba时
a
<
b
k
,
T
(
n
)
=
O
(
n
k
)
a<b^{k},T(n)=O(n^{k})
a<bk,T(n)=O(nk)