2022.5.12
算法中所有语句的频度之和记为T(n),它是该算法问题规模n的函数。
对于一个算法来说,循环体和递归是时间复杂度的重灾区,在这里先分析循环体的时间复杂度。
预备知识:
1.常见渐进时间复杂度
O(1)
2.计算时间复杂度时,系数可省略,O记法只看加项的最高阶
[例1]
void fun(int n)
{
int i=1; //语句频度1,后期可以忽略
while(i<=n) //i<=n是循环条件
i=i*2; //i=i*2控制循环次数
}
这里我们计算时间复杂度需要计算的就是循环体的语句频度。
设循环次数:t
根据循环体可得:2t<=n,此时循环可以继续下去
接下来只需求解出:t<=log2n,即可得到T(n)=O(log2n)
此时的t对应的就是语句的频度。
[例2]
void fun(int n)
{
int i=1; //语句频度1,后期可以忽略
while(i*i*i<=n) //i*i*i<=n是循环条件
i++; //i++和i*i*i控制循环次数
}
这里我们依旧计算循环体的语句频度。
设循环次数:t
根据循环体可得:t=i,t3<=n,此时循环可以继续下去
接下来只需求解出:t<=3√n ,即可得到T(n)=O(3√n)
此时的t对应的就是语句的频度。
[例3]
void fun(int n)
{
int x=2; //语句频度1,后期可以忽略
while(x<n/2) //x
x=2*x; //x=2*x和n/2控制循环次数
}
这里我们依旧计算循环体的语句频度。
设循环次数:t
根据循环体可得:2t+1
此时的t对应的就是语句的频度。
[例4]
void fun(int n)
{
int x=0; //语句频度1,后期可以忽略
while(n>=(x+1)*(x+1)) //n>=(x+1)*(x+1)是循环条件
x=x+1; //x=x+1和(x+1)*(x+1)控制循环次数
}
这里我们依旧计算循环体的语句频度。
设循环次数:t
根据循环体可得:(t+1)2<=n,此时循环可以继续下去
接下来只需求解出:t<=√n-1 ,即可得到T(n)=O(√n)
此时的t对应的就是语句的频度。
[例5]
void fun(int n)
{
int count=0; //语句频度1,后期可以忽略
for(k=1;k<=n;k*=2) //k<=n是循环条件
for(j=1;j<=n;j++) //j<=n是循环条件
count++; //k*=2和j++控制循环次数
}
这里我们依旧计算循环体的语句频度。
设循环次数:t1和t2
根据循环体可得:2t1<=n且t2<=n,此时循环可以继续下去
接下来只需求解出:t1<=log2n和t2<=n ,总循环次数t=t1xt2,即可得到T(n)=O(nlog2n)
此时的t对应的就是语句的频度。
[例6]
void fun(int n)
{
for(i=n-1;i>1;i--) //i>1是循环条件
for(j=1;j<i;j++) //j
if(A[j]>A[j+1]; //i--和j++控制循环次数
A[j]与A[j+1]互换;
}
这里的循环体是多层嵌套且相互关联的,所以在计算时要采用其它方式。
由循环体可以列出:
T ( n ) = ∑ i = 2 n − 1 ∑ j = 1 i − 1 1 = ( n − 1 ) ( n − 2 ) 2 T(n)=∑_{i=2}^{n-1} ∑_{j=1}^{i-1}1 =\displaystyle { \frac{(n-1)(n-2)}{2} } T(n)=i=2∑n−1j=1∑i−11=2(n−1)(n−2)
直接得到T(n)=O(n2)
[例7]
void fun(int n)
{
int m=0,i,j; //语句频度1,后期可以忽略
for(i=1;i<=n;i++) //i<=n是循环条件
for(j=1;j<=2*i;j++) //j<=2*i是循环条件
m++; //2*i和i++和j++控制循环次数
}
由循环体可以列出:
T ( n ) = ∑ i = 1 n ∑ j = 1 2 i 1 = ( 2 n + 2 ) n 2 T(n)=∑_{i=1}^{n } ∑_{j=1}^{2i}1 =\displaystyle { \frac{(2n+2)n}{2} } T(n)=i=1∑nj=1∑2i1=2(2n+2)n
直接得到T(n)=O(n2)
[例8]
void fun(int n)
{
int m=0;
for(i=1;k<=n;i++) //k<=n是循环条件
for(j=1;j<=i;j++) //j<=i是循环条件
for(k=1;k<=j;k++) //k<=j是循环条件
m++; //k++和i++和j++控制循环次数
}
由循环体可以列出:
T ( n ) = ∑ i = 1 n ∑ j = 1 i ∑ k = 1 j 1 = [ ( n + 1 ) n 2 + 1 ] ∗ n / 2 T(n)=∑_{i=1}^{n } ∑_{j=1}^{i}∑_{k=1}^{j}1 =[\displaystyle { \frac{(n+1)n}{2} +1]*n/2} T(n)=i=1∑nj=1∑ik=1∑j1=[2(n+1)n+1]∗n/2
直接得到T(n)=O(n3)
所有题目来自王道书。
可以对比例5和后面几个多层循环,当不同的层互不影响时,就能够将不同层分开计算。