算法的时间复杂度O
Posted guanghe
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法的时间复杂度O相关的知识,希望对你有一定的参考价值。
一、时间复杂度
在进行算法分析时,语句总的执行次数 T(n) 是关于问题的规模n 的函数,进而分析 T(n) 随 n 的变化情况并确定 T(n) 的数量级,算法的时间复杂度,也就是算法的时间度量,记作:T(n) = O(f( ))。它表示随问题的规模 n 的增大,算法的执行时间的增长率 f(n) 的增长率相同,称作算法的渐近时间复杂度,简称为时间的复杂度,其中 f(n) 是问题规模n的某个函数。
这样用大写 [ O( ) ] 来体现算法时间复杂度的记法,我们就称之为大O记法。例如:O(n)、O(1)、O(n2)、O(log n) 等等。一般情况下,随着 n 的增大,T(n) 增长最慢的算法为最优算法。
二、推导大O阶的方法
1,用时间1取代运算时间中的所有加法常数。
2,在修改后的运行的函数中,只保留最高阶项。
3,如果最高阶项存在且不是1,则去除与这个项相乘的常数。得到的结果就是大O阶。
例1:时间复杂度为O(1)常数阶的算法
1 int sum = 0, n = 100; /* 执行一次 */
2 sum = (1+n) *n/2; /* 执行一次 */
3 printf("the sum is:%d",sum); /* 执行一次 */
我们可以看出运行次数的函数是 f(n) = 3。根据我们上面的大O阶公式 1 可以得到,把常数项 3 改为 1,在保留最高阶时发现没有最高阶项,所以时间复杂度为大 O(1)。也就是说,无论算法是 3 次还是 30 次,哪怕是 300 次,这些只要是常数项,它的时间复杂度都为大 O(1),而不是O(3)、O(30)、O(300)。即我们称之为常数阶。
例2:时间复杂度为O(n)线性阶的算法
1 for(int i = 0; i < n; i++)
2 sum += i;
3
从上面的这段代码我们可以看出,它的时间复杂度为O(n),因为循环体中的代码需要执行n次。
例3:时间复杂度为O(n2)平方阶的算法
1 for(int i = 0; i < n; i++)
2 for(int j = i; j < n; j++)
3 //时间复杂度为O(n2)
4
5
分析:
当 i = 0时,内循环执行了 n 次,
当 i = 1时,内循环执行了 n-1 次,
......
当 i = n-1时。执行了 1 次,
所以总的执行次数为:n = (n-1)+(n-2)+ ··· + 1= n(n+1)/2 = n2/2+n/2。
由上面的公式可得:第一条代码中没有加法常数项,不考虑;第二条只保留最高阶项,因此保留 n2/2;第三条去除这个项相乘的常数,所以去除了 1/2;最终我们得到的代码段时间复杂度就是 O(n2)。
例4:时间复杂度为O(log n)对数阶的算法
1 int count = 1;
2 while (count < n)
3 count *= 2;
4
上面代码我们可以看出,count = count * 2 之后就距离 n 更近一步,也就是说,有多少个 2 相乘后大于 n,就退出循环。所以我们可以由 2x = n 推导出 x = log2n ,像这样的循环时间复杂度,我们就称为对数阶的复杂度即为 O(log n)。
三、O阶算法效率排序
数据结构中我们一般常用的时间复杂度表示有:O(1)、O(n)、O(n2)、O(log n)、O(nlog n)、O(n3)、O(2n)。
按时间复杂度所耗费的时间从大到小排序依次为:
O(1) < O(log n) < O(n) < O(nlog n) < O(n2) < O(n3) < O(2n)
以上是关于算法的时间复杂度O的主要内容,如果未能解决你的问题,请参考以下文章