概念
算法的复杂度分析包括空间复杂度分析和时间复杂度分析。
对于现代计算机,内存已经比较足够,对算法效率影响最大的是时间复杂度。
在时间复杂度的分析中,抛开具体机器,我们主要研究的是运行的语句数量。
运行的语句数量取决于需要处理的元素个数和算法的循环结构。
引入函数 f ( n ) f(n) f(n)来表示一个算法的效率,其中 n n n表示要处理的数据量。
几种典型循环结构的效率
效率分析我们主要关注循环结构,现就几种典型的循环结构探讨它的算法效率公式:
- 线性循环(linear loops)
- 对数循环(logarithmic loops)
- 嵌套循环(nested loops)
- 线性对数循环(linear logarithmic)
- 多项式循环(quadradic)
- 依赖多项式循环(dependent quadratic)
线性循环
i=0;
while(i<n){
//应用代码;
i=i+1;
}
在这个结构中,应用代码会执行n次。
运行的语句数量与处理的数据量成正比。
这一部分的效率函数可以表示为:
f
(
n
)
=
n
f(n)=n
f(n)=n。
同理:
i=0;
while(i<n){
//应用代码;
i=i+2;
}
这一部分的效率函数可以表示为: f ( n ) = n / 2 f(n)=n/2 f(n)=n/2。
对数循环
i=0;
while(i<n){
//应用代码;
i=i*2;
}
在这个结构中,应用代码会执行
l
o
g
2
(
n
)
log_2(n)
log2(n)次。
这一部分的效率函数可以表示为:
f
(
n
)
=
l
o
g
2
(
n
)
f(n)=log_2(n)
f(n)=log2(n)。
同理:
i=n;
while(i>=1){
//应用代码;
i=i/2;
}
这一部分的效率函数可以表示为: f ( n ) = l o g 2 ( n ) f(n)=log_2(n) f(n)=log2(n)。
线性对数循环
i=1;
while(i<n){
j=1;
while(j<n){
//应用代码;
j=j*2;
}
i=i+1;
}
内层循环为对数循环,应用代码执行次数为
l
o
g
2
(
n
)
log_2(n)
log2(n)。
外层循环为线性循环,内层代码执行次数为
n
n
n,因此对数循环总共执行
n
n
n次。
应用代码执行总次数为
n
∗
l
o
g
2
(
n
)
n*log_2(n)
n∗log2(n)。
这一部分的效率函数可以表示为:
f
(
n
)
=
n
∗
l
o
g
2
(
n
)
f(n)=n*log_2(n)
f(n)=n∗log2(n)。
多项式循环
i=1;
while(i<n){
j=1;
while(j<n){
//应用代码;
j=j+1;
}
i=i+1;
}
对于内层循环,应用代码执行
n
n
n次;对于外层循环,内部结构执行
n
n
n次。
应用代码总共执行
n
2
n^2
n2次。
因此,这一部分的效率函数可以表示为:
f
(
n
)
=
n
2
f(n)=n^2
f(n)=n2。
依赖多项式循环
i=1;
while(i<n){
j=1;
while(j<i){
//应用代码;
j=j+1;
}
i=i+1;
}
对于内层循环,应用代码的执行次数取决于外层循环,平均执行次数为
(
n
+
1
)
/
2
(n+1)/2
(n+1)/2。
外层循环的执行次数为
n
n
n。
应用代码总共执行
n
∗
(
n
+
1
)
/
2
n*(n+1)/2
n∗(n+1)/2次。
因此,它的效率函数可以表示为:
f
(
n
)
=
n
∗
(
n
+
1
)
/
2
f(n)=n*(n+1)/2
f(n)=n∗(n+1)/2。
求效率函数的一般方法
i=1;
while(i<n){
j=1;
while(j<i){
//应用代码;
j=j+1;
}
i=i+1;
}
k=n;
while(k>=1){
//应用代码;
k=k/2;
}
对于嵌套的循环结构,执行次数为外层循环次数乘以内层循环次数;对于并列的循环结构,执行次数为将两个循环的次数相加。上述代码的算法效率公式为 f ( n ) = n 2 + l o g 2 ( n ) f(n)=n^2+log_2(n) f(n)=n2+log2(n)。
Big-O 表达式
表示某一算法的效率处在哪一个档次。
计算方法:
- 保留算法效率公式 f ( n ) f(n) f(n)的最高次项(算法复杂程度最高的项),摄取其余项。
- 将其系数设为1。
- 项的复杂程度由低到高分别为: l o g 2 ( n ) log_2(n) log2(n), n n n, n ∗ l o g 2 ( n ) n*log_2(n) n∗log2(n), n 2 n^2 n2, n 3 n^3 n3, …, n k n^k nk, 2 n 2^n 2n, n ! n! n!。
例如:
f
(
n
)
=
4
∗
n
3
+
n
∗
l
o
g
2
(
n
)
+
50
∗
l
o
g
2
(
n
)
f(n)=4*n^3+n*log_2(n)+50*log_2(n)
f(n)=4∗n3+n∗log2(n)+50∗log2(n)
- 最高次项为: 4 ∗ n 3 4*n^3 4∗n3
- 系数设为1: n 3 n^3 n3
因此,这个算法的Big-O表达式为: O ( n 3 ) O(n^3) O(n3)