复杂度分析
-
声明的赋值度: 无
-
每条赋值的复杂度:1
-
每条判断的复杂度:1
-
判断的分支:计算所有情况中复杂度较大者
-
返回return的复杂度:1
但是注意若一个函数中有多个return ,执行时只执行其中一个,只能算一次。
若返回return中仍有表达式,不算复杂度
float rsum ( float list[ ], int n )
{ /* add a list of numbers */
if ( n ) //判断 1
return rsum(list, n - 1) + list[n - 1];//return中的表达式不算,return 1次
return 0;//多个return只算一次
}
- 递归的复杂度:
retun 算一次,return中调用该函数的,调用几次,各自计算
列递推关系式求解,比如上方的是 T(n) = T(n-1) + 2
解得T(n) = 2n + 2
复杂的递归式这里不做解法分析
- 循环的复杂度:
对于for循环从0到n,循环体中的内容执行n次,for语句的循环变量执行n+1次
故总执行次数 = n+1+n*(循环体中语句执行次数)
比如代码
void add ( int a[ ][ MAX_SIZE ],
int b[ ][ MAX_SIZE ],
int c[ ][ MAX_SIZE ],
int rows, int cols )
{
int i, j ;//声明复杂度无
for ( i = 0; i < rows; i++ )//对于该循环体,复杂度为rows+1+rows(i的内部)
for ( j = 0; j < cols; j++ )//对于i的内部,复杂度为cols+1+cols(j的内部)
c[ i ][ j ] = a[ i ][ j ] + b[ i ][ j ];//j的内部=1
}
总的复杂度为:rows+ 1 + rows(cols + 1 + cols * 1) = 2 rows * cols + 2rows + 1
复杂度符号
符号 | 意义 |
---|---|
O ( N ) O(N) O(N) | 复杂度上界 |
Ω ( N ) \Omega(N) Ω(N) | 复杂度下界 |
Θ ( N ) \Theta(N) Θ(N) | 复杂度的常数倍 |
o ( N ) o(N) o(N) | 是上界,但不是常数倍(O(N)可能和 Ω \Omega Ω相等,但是o(N)要求大于 Ω \Omega Ω) |
比较:
o ( N ) > N o(N)>N o(N)>N
O ( N ) ≥ Θ ( N ) = c ∗ N ≥ Ω ( N ) O(N)\ge \Theta(N)=c*N\ge\Omega(N) O(N)≥Θ(N)=c∗N≥Ω(N)
大致分析:
循环:循环内部的乘其外部所有循环的次数之积
相加后总是考虑更大的部分
题目
1.The Fibonacci number sequence {FN } is defined as: F0 =0, F1 =1, FN =FN−1 +FN−2 , N=2,3,… The time complexity of the function which calculates FN recursively is Θ(N!).(3分)
计算斐波那契数列复杂度为 1. 5 N < Θ ( N ) < 2 N 1.5^N<\Theta(N)<2^N 1.5N<Θ(N)<2N,N!显然比 2 N 2^N 2N大,故选F
2.n^0.01 is O(logn)
n的多少次最后都比logn大,故选F
3.For the following piece of code
if ( A > B ){
for ( i=0; i<N*2; i++ )
for ( j=N*N; j>i; j-- )
C += A;
}
else {
for ( i=0; i<N*N/100; i++ )
for ( j=N; j>i; j-- )
for ( k=0; k<N*3; k++)
C += B;
}
the lowest upper bound of the time complexity is O(N^3).
if中复杂度为N^3,注意N*2不是N平方,else复杂度为N * N * N(当i到n的时候就不进去了,因此外循环按N算,答案为T)
4.Given the following four algorithms with their runtimes for problem size 100 and their time complexities
Which algorithm is the fastest for problem size 200?
给了一些O(f(N)),当N=100时的复杂度,问N=200时的复杂度。
O(x)是近似线性的,所以直接按照f(2N)增大的倍数算
5.Let n be a non-negative integer representing the size of input. The time complexity of the following piece of code is:
x = 0;
while ( n >= (x+1)*(x+1) )
x = x+1;
循环结束的条件是 x + 1 < N x+1<\sqrt{N} x+1<N,故为O(N^0.5)
6.The recurrent equations for the time complexities of programs P1 and P2 are:
P1: T(1)=1,T(N)=T(N/3)+1
P2: T(1)=1,T(N)=3T(N/3)+1
Then the correct conclusion about their time complexities is:
求递归复杂度,一种方法是直接代入法:
T(N)=T(N/3)+1
T(N/3) = T(N/9)+1
…
T(N) = T(N/3)+1 = T(N/9) + 2 = …=T(N/3^k) + k
加到T(1)为止,所以
N = 3 ^ k,
k = c * log(N)
T(N) = c*log(N)+T(1)
类似可得T(N) = 3 ^ k T( N/3 ^ k ) + 3 ^ n-1 + …3 + 1
N = 3^k
最后可得T(N) = O( N)
7.To judge an integer N (>10) is prime or not, we need to check if it is divisible by any odd number from 3 to √N . The time complexity of this algorithm is __.
题目说N ^ 0.5的奇数,所以还是O(N ^ 0.5)
8.The Fibonacci number sequence {FN } is defined as: F0 =0, F1 =1, FN =FN−1 +FN−2 , N=2, 3, … The space complexity of the function which calculates FN recursively is:
空间复杂度为O(N)
9.For the following function
int func ( int n )
{ int i = 0, sum = 0;
while ( sum < n ) sum += ++i;
return i;
}
the time complexity is:
(5分)
A.O(nlogn)
B.O(logn)
C.O(n)
D.O(n1/2 )
注意i会自加,因此其实sum=1+2+…+N,sum=O(N^2),n=O(N ^0.5)
注意点
循环了几次,是N还是N^2
循环中是所有的数都做了吗?
递归式怎么求复杂度
如果循环变量在表达式中不是n,那么化为n
i ^ 0.5 < N,化为 i < N ^ 2,故循环的是O(N^2)