算法的时间与空间复杂度
一、算法的时间复杂度
1、算法的执行时间和频度
!*首先明确一下一些专业术语的概念
*算法的执行时间=所有语句执行时间的总和
*语句执行时间=该语句重复执行次数×该语句每执行一次所需时间
*频度:一条语句重复执行的次数
!*(!*在本文中代表要注意的知识点)算法实际所需的具体时间与机器的软硬件环境(机器速度、编译程序质量等)相关;因此可以设每条语句执行一次所需时间是单位时间,所以一个算法的执行时间即所有语句频度之和。
2、问题规模和算法时间复杂度
*规模(有些书中称之为模块):算法求解问题的输入量。通常用n表示。
例:
矩阵的阶数;多项式的项数;排序时数的个数;一个图中的顶点数或边数;集合中的元素个数。
*数量级‘O ':
数学定义:若T(n)和f(n)是定义在整数集合上的两个函数,则T(n)=O(f(n))表示,存在常数c>0和n0,使得当n>n0时都满足0<=T(n)<=cf(n).
*时间复杂度:一个算法的时间复杂度是该算法的执行时间。记作T(n)(该函数是n的函数)。设一个函数是f(n)(找的这个函数是为了方便我们进行比较),T(n)和f(n)是同阶的(此处可联系高数求极限时的同阶无穷小,即两函数相除,当n→∞时,极限为常数c),则可说T(n)和f(n)的数量级相同,记作:
T(n)=O(f(n))
T(n)称为算法的渐近时间复杂度,简称时间复杂度。
!*上面公式可以这样理解:随着模块n的增加,算法执行时间的增长率和f(n)的增长率成正比,所以f(n)越小,T(n)越小,算法效率越高。
ps:T(n)与f(n)都是增长的,当过了某一个点时两个函数的函数值成正比,每点的增长率自然也成正比,不过前提是n→∞,当n没有足够大时,是体现不出来的。
例:
T(n)=2n^3+3n^2+2n+1
f(n)=n^3
limT(n)/n^3=lim(2n^3+3n^2+2n+1)/n^3=2;
!*(lim符号下应是n→∞)
通过上式便可记为T(n)=O(n^3).
3、时间复杂度计算方法
*步骤
(1)、先跟据算法确定它的执行次数(其实只要保证基本语句执行次数中最高次幂正确即可,即频度最大的语句的次数,其实这个可以联系上个例子,其余项的极限为0,所以可以忽略)。
(2)、找出T(n)的同数量级,通常有以下函数:
O(1)<O(log2n)<O(n)<O(nlog2n)<O(n^2)<O(n^3)<...<O(n^k)<O(2^n)<O(n!)
!*O(log2n),O(n),O(nlog2n),O(n^2),O(n^3)称为多项式时间,而O(2^n),O(n!)称为指数时间。前者为有效算法,为P类问题,而后者,当n无限大时可以想象其速度增长之快,为NP类问题。
*求算法的一些计算法则
1、对于一些简单的输出输入算法或算法中不存在循环语句,其时间复杂度就认为是O(1)。
2、对于顺序结构,需要依次执行的语句可用求和法则
*求和法则
若算法的2个部分的时间复杂度分别为T1(n)=O(f(n)),T2(n)=O(g(n))则
T1(n)+T1(n)=O(max(f(n),g(n)))
特别的,若T1(m)=O(f(m)),T2(n)=O(g(n)), 则
T1(m)+T2(n)=O(f(m)+g(n))
3、对于选择结构,如if语句,主要时间耗费是在执行then或else字句,需注意的是,检验条件也需要O(1)的时间。
4、循环结构—————乘法法则
* 乘法法则
若算法的2个部分的时间复杂度分别为T1(n)=O(f(n)),T2(n)=O(g(n))则
T1(n)*T1(n)=O(f(n)*g(n))
5、对于复杂的算法,可以将它分为几个容易估算的部分,再利用求和或乘法法则求得结果。
还有另外2个运算法则:
(1)、g(n)=O(f(n)),则O(f(n))+O(g(n))=O(f(n))
(2)、O(cf(n))=O(f(n)),其中c为常数
在此说明一个例子:
(1)for (i=0;i<n;i++)
(2)if (a[i]==e) return i+1;
(3)return 0;
* 分析:若a[0]=e,则T(n)=O(1);若e为a[n-1]或不存在,则T(n)=O(n)。
!*由上面的例子可以出T(n)不仅和问题的规模大小有关,与问题数据的初始状态也有关。
*由此便产生最好,最坏以及平均状态下的时间复杂度的概念,人们更关心最坏情况,拿过一个算法来可以讨论分析最坏情况下,算法执行时间的上界。
最后附上一道题计算该算法的时间复杂度,检验一下你的掌握情况:
(1)x=1;
(2)for(i=1;i<n;i++)
(3) for(j=1;j<i;j++)
(4) for(k=1;k<j;k++)
5
解析:∑(下:i=1,上:n)∑(下:j=1,上:i)∑(下:k=1,上:j)1=∑(下:i=1,上:n)∑(下:j=1,上:i)j=∑(下:i=1,上:n)i(i+1)/2=
[n(n+1)(2n+1)/6+n(n+1)/2]/2
T(n)=O(n^3)
还会用到n^2的前n项和公式,1+4+......+n^2=n(n+1)(2n+1)/6
二、算法的空间复杂度(SpaceComplexity)
*空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度,也是规模n的函数,记作:
S(n)=O(f(n))
!*其中对于输入数据所占的空间取决于问题本身,与算法无关,只需分析该算法在实现使所需要的辅助空间(临时占用的存储空间)即可。