算法运行时间的度量---时间频度
用算法中标准操作即基本语句的执行次数来度量运行时间。
>基本语句执行次数越多,时间花费越多,执行次数称时间频度。
>时间频度和处理的数据规模n有关,可表示为n的函数T(n)。
s =0执行1次,i=0执行1次,i<n执行n+1次,i++执行n次,s = s+i执行n次,共计执行标准操作3n+3次。
s = 0;
for (i=0; i<n; i++)
s = s+i;
故算法的时间频度为T(n)=3n+3。
Ø 循环语句 --- 需要 计算实际运行的次数 ,不是 看语句书写的次数。
Ø 分支语句 --- 按照 执行语句多的那个分支计算 。
如:
if (n>0)
{ for (i=0; i<n; i++) cout<<i; }
else
cout<<"n<=0!";
n>0时,为3n+3次;n<=0时,为1次。时间频度为3n+3。
时间复杂度定义
如果当n趋于无穷时,T(n)/f(n)的极限为一个非零常数,称O(f(n))为算法的渐进时间复杂度,简称时间复杂度。
这种形式称为大O表示法。
即∃C和𝑁0, ∀n>𝑁0,有Tn≤C∗f(n),则O(f(n)) 为算法的时间复杂度
例子1: T(n)=3𝑛2+2𝑛+10
Tn≤3𝑛2+2𝑛2+10𝑛2≤15𝑛2
存在𝑁0=1, 𝐶=15,当n>𝑁0时,有Tn≤15∗𝑛2,
即fn=𝑛^2,算法的复杂度为O(n^2)。
例子2: 当T(n)=3n+3时,T(n)≤6nT(n)≤6n ,时间复杂度为O(n)
时间复杂度由时间频度函数中的最高次项决定,不带系数。
时间复杂度的计算方法
1. 找算法中和数据规模 n 有关的循环语句,计算循环体的执行次数获得时间频度函数。
2. 观察时间频度函数中关于 n 的最高次项,去掉其系数,即是时间复杂度的大 O 表示。
特殊地:如果算法中无执行次数和数据规模n的相关语句,即时间频度函数是一个常量,则时间复杂度为O(1)。
常见算法的时间复杂度:
常量阶O(1)、对数阶O(log2𝑛log_2n)、线性阶O(n)、线性对数阶O(nlog2𝑛log_2n)、平方阶O(𝑛2n^2)、立方阶O(𝑛3)、n^3)、幂阶O(2𝑛)(2^n)、阶乘阶O(n!)、N幂阶O(𝑛𝑁n^N)。
注意:不仅限于这几种
Ø按照上面顺序,时间效率由高到低。
Ø到达立方阶之后,一旦数据规模大些,时间就已经是不能忍受了,是一个顽性算法;
Ø从常量级到平方级,通常称易性算法。
计算时间复杂度的简化工具
求和定理
求和定理:假定T1(n)、T2(n)是程序P1、P2的运行时间,并且T1(n)是O(f(n))的,而T2(n)是O(g(n))的。那么,先运行P1、再运行P2的总的运行时间是:T1(n)+T2(n)=O(MAX(f(n),g(n))。
for (i=0; i<n; i++) a[i]=O;//第一段
for (i=0; i<n; i++)//第二段
for (j=0; j<n; j++) a[i]= i+j;
按照求和定理为O(max(n, n2))=O(n2)
求积定理
求积定理:如果T1(n)和T2(n)分别是O(f(n))和O(g(n))的,那么T1(n)×T2(n)是O(f(n)× g(n))的。
for (i=O; i<n; i++)
for (j=0; j<n; j++)
{s=s+i+j; cout<<s; }
按照求积定理,为O(n*n)=O(n2)
1、通常考虑三个方面:最好情况的时间复杂度、最坏情况的时间复杂度和平均情况的时间复杂度。
2、大O表示法中,O是数量级order的首字母。
3、O(f(n))并不描述运行时间的精确值,只给出一个数量级。4、它表示:当问题规模很大时,算法运行时间的增长受限于哪一个数量级的函数,简称为量阶。