算法复杂度
算法效率的度量是通过时间复杂度和空间复杂度来描述的。
时间复杂度
在计算机科学中,算法的时间复杂度是一个函数,定量描述了一个算法的运行时间。一个算法花费的时间和算法中语句的执行次数成正比。 一个算法中语句执行次数称作语句频度或时间频度,将所有语句总的执行次数用T(n)
来表示。其中n
是指问题的规模。算法的时间复杂度也就是算法的时间度量,记做:T(n) = O(f(n))
,表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度。
常见的渐进时间复杂度为:
O(1) < O(log~2~n)<O(n) <O(nlog~2~n)<O(n^2^)<O(n^3^)< …<O(2^n^)<O(n!)
求解算法的时间复杂度的步骤为:
- 找出算法中的基本语句:
算法中执行次数最多的那条语句就是基本语句,通常是最内层循环的循环体。 - 计算基本语句的执行次数的数量级:
只需计算基本语句执行次数的数量级,这意味着只要保证基本语句执行次数的函数中的最高次幂正确即可。可以忽略所有低次幂和最高次幂的系数。这样能够简化算法分析,并能使注意力集中在最重要的一个点上:增长率。 - 用大O记号表示算法的时间性能:
将基本语句执行次数的数量级放入在大O记号中。
如果算法中包含嵌套的循环,则基本语句通常是最内层的循环体,如果算法中包含并列的循环,则将并列循环的时间复杂度相加。
例:
(1). O(1)Temp=i; i=j; j=temp;
以上三条单个语句的频度均为1,该程序段的执行时间是一个与问题规模n无关的常数。算法的时间复杂度为常数阶,记作T(n)=O(1)。注意:如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。
(2). O(n^2^)1
2
3
4
5
6sum = 0; 1次
for(i=1;i<=n;i++){ n+1次
for(j=1;j<=n;j++){ n^2^次
sum++; n^2^次
}
}
因为Θ(2n^2^+n+1)=n^2^(Θ即:去低阶项,去掉常数项,去掉高阶项的常参得到),所以T(n)= =O(n^2^);
1 | for(i=1;i<n;i++){ |
f(n)=2n2-n-1+(n-1)=2n2-2; 又Θ(2n2-2)=n2
该程序的时间复杂度T(n)=O(n2).
一般情况下,对步进循环语句只需考虑循环体中语句的执行次数,忽略该语句中步长加1、终值判别、控制转移等成分,当有若干个循环语句时,算法的时间复杂度是由嵌套层数最多的循环语句中最内层语句的频度f(n)决定的。
(3). O(n)1
2
3
4
5
6
7a =0 ;
b=1; 频度为2
for(i = 1;i<=n;i++){ 频度 n
s =a +b; 频度 n-1
b =a; 频度 n-1
a = s; 频度 n-1
}
T(n) = 2+ n + 3(n-1) = 4n-1= O(n)
(4). O(log~2~n)
1 | i =1; 频度为1 |
设语句2的频度是f(n), 则:2^f(n)<=n; f(n)<=log~2~n
取最大值f(n)=log~2~n, T(n)=O(log~2~n )
(5). O(n^3^)
1 | for(i=0;i<n;i++){ |
空间复杂度
算法的空间复杂度S(n)
, 一个算法在计算机存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面。
总的来说,空间复杂度是除正常内存开销外的辅助存储单元规模。
参考资料 :