计算时间复杂度
2018-03-17 12:57
162 查看
求解算法的时间复杂度,步骤如下:(1)找出算法中的基本语句: 算法中执行次数最多的那条语句就是基本语句,通常是最内层循环的循环体(2)计算基本语句的执行次数的数量级 只需要计算基本语句执行次数的数量级,这就意味着只要保证基本语句执行次数的函数中的最高次幂正确即 可,可以忽略所有低次幂和最高次幂的系数,这要能够简化算法分析,并且使注意力集中在最重要的一点上:增长率 。 (3)用大0记号表示算法的时间性能 将基本语句执行次数的数量级放入放入大0记号中 如果算法中包含嵌套的循环,则基本语句通常是最内层的循环体,如果算法中包含并列的循环体,则将并列 的时间复杂度相加。例如: for(i=1;i<=n;i++) x++; for(j=1;j<=n;j++) for(i=1;i<=n;i++) x++; 第一个for循环的时间复杂度为0(n),第二个for循环的时间复杂度为0(n2),则整个算法的时间复杂度为 0(n+n^2)=0(n^2) 常见的算法复杂度由小到大依次为: 0(1)<0(log2n)<0(n)<0(nlog2n)<0(n2)<(n3)<···<0(2n)<0(n!) 0(1)表示基本语句的执行次数是一个常熟,一般来说只要算法中不存在循环语句,其时间复杂度就为0(1). 0(log2n)、0(n)、0(nlog2n)、0(n2)和0(n3)称为多项式时间,而0(2n)和0(n!)称为指数时间。 计算机科学家认为前者是有效算法,这类问题成为P(多项式)类问题,而把后者称为NP(非确定多项式)类问题 在计算算法时间复杂度时有以下几个简单的程序分析法则: (1).对于一些简单的输入输出语句或赋值语句,近似认为需要0(1)时间 (2).对于顺序结构,需要依次执行一系列语句所用的时间可采用大0下(求和法则) 求和法则:是指若算法的2个部分时间复杂度分别为T1(n)=0(f(n))和T2(n)=0(g(n)),则T1(n)+T2(n)=0 (max(f(n),g(n))).t特别的,若T1(m)=0(f(m)),T2(n)=0(g(n)),则T1(m)+T2(n)=0(f(m)+g(n)) (3).对于选择结构,如if语句,它的主要时间耗费都在执行then语句或需注意的是检验条件也需要0(1)时间
(4).对于循环结构,循环语句的执行时间主要体现在多次迭代中执行循环体以及检验循环条件的时间耗费, 一般可以大0下(乘法法则) 乘法法则:是指若算法的2个部分时间复杂度分别为T1(n)=0(f(n))和T2(n)=0(g(n)),则T1*T2=0(f(n)*g(n)) (5). 对于复杂的算法,可以将它分成几个容易估算的部分,然后利用求和法则和乘法法则计算整个算法的时间复杂度 另外还有以下两个运算法则: (1)若g(n)=0(f(n)),则0(f(n))+0(g(n))=0(f(n)) (2)0(Cf(n))=0(f(n)),其中C是一个正整数 几个常见的时间复杂度进行示例说明(1)、O(1) Temp=i; i=j; j=temp;
以上三条单个语句的频度均为1,该程序段的执行时间是一个与问题规模n无关的常数。算法的时间复杂度为常数阶,记作T(n)=O(1)。注意:如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。
(2)、O(n2)交换i和j的内容
1.sum=0;(一次) 2.for(i=1;i<=n;i++) (n+1次) 3.for(j=1;j<=n;j++)(n(n+1)次) 4.sum++;(n(n+1)+1次)
因为(2n2+n+1)=n2(即:去低阶项,去掉常数项,去掉高阶项的常参得到),所以T(n)= =O(n2);
一般情况下,对步进循环语句只需考虑循环体中语句的执行次数,忽略该语句中步长加1、终值判别、控制转移等成分,当有若干个循环语句时,算法的时间复杂度是由嵌套层数最多的循环语句中最内层语句的频度f(n)决定的。
(3)、O(n)
1.a=0; 2.b=1; ① 3.for (i=1;i<=n;i++) ② 4.{s=a+b; ③ 6.b=a; ④ 7.a=s;
} ⑤ 语句1的频度为2,语句2的频度为n,语句3的频度为n-1,语句4的频度为n-1,语句5的频度为n-1, 即T(n)=2+n+3(n-1)=4n-1=O(n).
(4)、O(log2n) 1. i=1; ① 2. while (i<=n) 3. i=i*2; ② 语句1的频度是1,设语句2的频度是f(n),则:2^f(n)<=n;f(n)<=log2n,取最大值f(n)=log2n,即T(n)=O(log2n)
(5)、O(n3) 1. for(i=0;i<n;i++){ 2. for(j=0;j<i;j++){ 3.for(k=0;k<j;k++) 4.x=x+2; }}当i=m,j=k的时候,内层循环的次数为k当i=m时, j可以取 0,1,...,m-1 ,所以这里最内循环共进行了0+1+...+m-1=(m-1)m/2次所以,i从0取到n,则循环共进行了:0+(1-1)*1/2+...+(n-1)n/2=n(n+1)(n-1)/6所以时间复杂度为O(n3).
(4).对于循环结构,循环语句的执行时间主要体现在多次迭代中执行循环体以及检验循环条件的时间耗费, 一般可以大0下(乘法法则) 乘法法则:是指若算法的2个部分时间复杂度分别为T1(n)=0(f(n))和T2(n)=0(g(n)),则T1*T2=0(f(n)*g(n)) (5). 对于复杂的算法,可以将它分成几个容易估算的部分,然后利用求和法则和乘法法则计算整个算法的时间复杂度 另外还有以下两个运算法则: (1)若g(n)=0(f(n)),则0(f(n))+0(g(n))=0(f(n)) (2)0(Cf(n))=0(f(n)),其中C是一个正整数 几个常见的时间复杂度进行示例说明(1)、O(1) Temp=i; i=j; j=temp;
以上三条单个语句的频度均为1,该程序段的执行时间是一个与问题规模n无关的常数。算法的时间复杂度为常数阶,记作T(n)=O(1)。注意:如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。
(2)、O(n2)交换i和j的内容
1.sum=0;(一次) 2.for(i=1;i<=n;i++) (n+1次) 3.for(j=1;j<=n;j++)(n(n+1)次) 4.sum++;(n(n+1)+1次)
因为(2n2+n+1)=n2(即:去低阶项,去掉常数项,去掉高阶项的常参得到),所以T(n)= =O(n2);
一般情况下,对步进循环语句只需考虑循环体中语句的执行次数,忽略该语句中步长加1、终值判别、控制转移等成分,当有若干个循环语句时,算法的时间复杂度是由嵌套层数最多的循环语句中最内层语句的频度f(n)决定的。
(3)、O(n)
1.a=0; 2.b=1; ① 3.for (i=1;i<=n;i++) ② 4.{s=a+b; ③ 6.b=a; ④ 7.a=s;
} ⑤ 语句1的频度为2,语句2的频度为n,语句3的频度为n-1,语句4的频度为n-1,语句5的频度为n-1, 即T(n)=2+n+3(n-1)=4n-1=O(n).
(4)、O(log2n) 1. i=1; ① 2. while (i<=n) 3. i=i*2; ② 语句1的频度是1,设语句2的频度是f(n),则:2^f(n)<=n;f(n)<=log2n,取最大值f(n)=log2n,即T(n)=O(log2n)
(5)、O(n3) 1. for(i=0;i<n;i++){ 2. for(j=0;j<i;j++){ 3.for(k=0;k<j;k++) 4.x=x+2; }}当i=m,j=k的时候,内层循环的次数为k当i=m时, j可以取 0,1,...,m-1 ,所以这里最内循环共进行了0+1+...+m-1=(m-1)m/2次所以,i从0取到n,则循环共进行了:0+(1-1)*1/2+...+(n-1)n/2=n(n+1)(n-1)/6所以时间复杂度为O(n3).
相关文章推荐