《数据结构》笔记
1. 关于递归法时间复杂度计算的主方法:
对于
T
(
n
)
T(n)
T(n)有
T
(
n
)
=
a
T
(
n
/
b
)
+
f
(
n
)
,
其
中
a
≥
1
,
b
>
1
,
f
为
渐
进
趋
正
T(n) = aT(n/b)+f(n),其中a≥1,b>1,f为渐进趋正
T(n)=aT(n/b)+f(n),其中a≥1,b>1,f为渐进趋正
Caes1:
f
(
n
)
=
O
(
n
l
o
g
b
a
−
ε
)
f(n)=O(n^{log^a_b-ε})
f(n)=O(nlogba−ε)需
ε
>
0
ε>0
ε>0时,则其复杂度为
T
(
n
)
=
Θ
(
n
l
o
g
b
a
)
T(n)=Θ(n^{log^a_b})
T(n)=Θ(nlogba)
Caes2:
f
(
n
)
=
O
(
n
l
o
g
b
a
l
o
g
k
n
)
f(n)=O(n^{log^a_b}log^kn)
f(n)=O(nlogbalogkn)需
k
≥
0
k≥0
k≥0时,则其复杂度为
T
(
n
)
=
Θ
(
n
l
o
g
b
a
l
o
g
k
+
1
n
)
T(n)=Θ(n^{log^a_b}log^{k+1}n)
T(n)=Θ(nlogbalogk+1n)
Caes2:
f
(
n
)
=
O
(
n
l
o
g
b
a
−
ε
)
f(n)=O(n^{log^a_b-ε})
f(n)=O(nlogba−ε)需
ε
>
0
ε>0
ε>0且对于
c
<
1
c<1
c<1时
a
f
(
n
/
b
)
≤
c
f
(
n
)
af(n/b)≤cf(n)
af(n/b)≤cf(n),则其复杂度为
T
(
n
)
=
Θ
(
f
(
n
)
)
T(n)=Θ(f(n))
T(n)=Θ(f(n))
其证明过程见《算法导论》B站bv号:BV1Tb411M7FA
Examples:分治法中使用递归过程的归并排序(Merge Sort)
对于n个未排序的数组 A A A,即 A [ 1 , ⋅ ⋅ ⋅ , n ] A[1,···,n] A[1,⋅⋅⋅,n](此处 1 − n 1-n 1−n表示数组元素位置)其排序过程如下:
- If n = 1 n=1 n=1,done.
- else 将数组 A A A分为两份 A [ 1 , ⋅ ⋅ ⋅ , n / 2 ] A[1,···,n/2] A[1,⋅⋅⋅,n/2],分别对两个 A [ 1 , ⋅ ⋅ ⋅ , n / 2 ] A[1,···,n/2] A[1,⋅⋅⋅,n/2]进行归并,
- 合并两个 A [ 1 , ⋅ ⋅ ⋅ , n / 2 ] A[1,···,n/2] A[1,⋅⋅⋅,n/2]数组。
对于第2个步骤会递归地进行步骤1,2,3。
由此可知按照步骤1,2,3的时间复杂度
T
(
n
)
=
Θ
(
1
)
+
2
T
(
n
/
2
)
+
Θ
(
n
)
T(n)=Θ(1)+2T(n/2)+Θ(n)
T(n)=Θ(1)+2T(n/2)+Θ(n),对应主方法,则
f
(
n
)
=
Θ
(
1
)
+
Θ
(
n
)
f(n)=Θ(1)+Θ(n)
f(n)=Θ(1)+Θ(n),此处
n
l
o
g
b
a
=
n
l
o
g
2
2
=
n
n^{log^a_b}=n^{log^2_2}=n
nlogba=nlog22=n,若其对应Case1,不满足
ε
>
0
ε>0
ε>0,若其对应Case2,
k
k
k取
0
0
0,满足
k
≥
0
k≥0
k≥0。
则有归并排序的时间复杂度为:
T
(
n
)
=
Θ
(
n
l
o
g
b
a
l
o
g
k
+
1
n
)
=
Θ
(
n
l
o
g
n
)
T(n)=Θ(n^{log^a_b}log^{k+1}n)=Θ(nlogn)
T(n)=Θ(nlogbalogk+1n)=Θ(nlogn)
也可画二叉树进行粗略证明(此处借用《算法导论》配套PPT):
T
(
n
)
=
2
T
(
n
/
2
)
+
c
n
T(n)=2T(n/2)+cn
T(n)=2T(n/2)+cn可用下图表示,其中cn即表示f(n)
每个
T
(
n
/
2
)
T(n/2)
T(n/2)同样进行分隔,以此类推则有如下所示:
由此,将最终的叶节点与递归次数相乘则有
T
(
n
)
T(n)
T(n)的时间复杂度:
T
(
n
)
=
Θ
(
n
l
o
g
n
)
T(n)=Θ(nlogn)
T(n)=Θ(nlogn)
2. 复杂度分析的部分技巧
- 若两段算法分别有复杂度
T
1
(
n
)
=
O
(
f
1
(
n
)
)
T_1(n)=O(f_1(n))
T1(n)=O(f1(n))和
T
2
(
n
)
=
O
(
f
2
(
n
)
)
T_2(n)=O(f_2(n))
T2(n)=O(f2(n)),则有:
- T 1 ( n ) + T 2 ( n ) = m a x ( O ( f 1 ( n ) ) , O ( f 2 ( n ) ) ) T_1(n)+T_2(n)=max(O(f_1(n)),O(f_2(n))) T1(n)+T2(n)=max(O(f1(n)),O(f2(n)))
- T 1 ( n ) × T 2 ( n ) = O ( f 1 ( n ) × f 1 ( n ) ) T_1(n)×T_2(n)=O(f_1(n)×f_1(n)) T1(n)×T2(n)=O(f1(n)×f1(n))
- 若 T ( n ) T(n) T(n)是关于 n n n的 k k k阶多项式,则 T ( n ) = Θ ( n k ) T(n)=Θ(n^k) T(n)=Θ(nk)
- 一个
for
循环的时间复杂度等于循环次数乘以循环体代码的复杂度 if-else
结构的复杂度取决于if
的条件判断复杂度和两个分支部分的复杂度,总体复杂度取三者中最大