您的位置:首页 > 其它

算法的复杂度度量--时间复杂度以及空间复杂度

2018-11-20 20:33 204 查看

数据结构和算法课程上都有关于时间复杂度的分析,但是自己一直都是一知半解,似乎懂却又不能解释清楚。希望这篇博客作为自己记录成长的开端!

为什么要有时间复杂度以及空间复杂度

评价一个算法有几大标准,主要包括Correctness(正确性),Amount of work done(工作量),Amount of space used(使用空间),Simplicity(简单性),Optimality(最优性)

其中正确性涉及到数学证明;工作量表示整个算法要干多少活,与机器以及输入密切相关,通过基本操作的数目来衡量,此时与时间复杂度相关联;使用空间即空间复杂度,至于简单性和最优性则属于算法的优化部分。

时间复杂度

衡量一个算法好坏最直接的,最容易想到的也就是该算法的计算速度,所需的计算时间,然而计算时间与很多因素相关,选择影响最大,最关键的因素-问题的规模(问题的输入规模)来进行考虑,将特定算法处理规模为n的问题所需的时间记为T(n)。

即使输入规模相同,输入的顺序也会影响计算时间(可以联想排序算法不同输入情况)时间复杂度分为3种情况:最好情况Tbest,Tave,Tworst。简化问题,往往考虑Tworst,即最坏情况下的时间复杂度。并考虑大规模问题,注重时间复杂度随问题规模扩大的总体变化趋势(渐进分析)(类似数学中的极限),引入大O记号来表示T(n)的渐进上界。

给出大O记号的定义:

存在正的常数和函数f(n),使得n>>2时有:
T(n)<=c*f(n)
则认为在n足够大时,T(n)有渐进上界,记为T(n)=O(f(n))

  • 注意时间复杂度往往更加关注在处理大规模问题时的表现,即n->无穷的情况,此时可以考虑数学中的极限,并有相关性质
  • O(f(n))中f(n)可以忽略常系数
  • O(f(n))中f(n)可以忽略低此项

上面给出了时间复杂度的度量,但具体到某一个问题时,如何找T(n)呢?
方法如下:

还是简化问题,将指令简化为一个个的具体操作,同时假定不同的操作都只占用一个时间单元,这样T(n)就转变成为算法执行基本操作的总次数,即看程序执行了多少次基本操作

下面给出实际例子:

在数组中找最大数

max=a[0];                 //1次赋值操作
for (i=1; i<n; i++)       //1次初始化i 1次初始化时的比较 循环开始后 n-1次比较  n-1次自增
{
if (a[i]>max)         //每次循环 1次比较
max=a[i];         //判断成功后 有1次赋值
}

在最坏情况下(即最大数在末尾,每次都会进入循环体内的赋值操作),整个程序一共有 1+1++1+4(n-1)=4n-1 次基本操作 即f(n)=4n-1

根据上述大O的性质:忽略常数项,忽略低此项,最后的T(n)=O(n)

典型的复杂度级别

O(1) 常数时间复杂度
O(logn) 对数时间复杂度
O(n) 线性
O(nlogn) 线性对数阶
O(2^n) 指数阶

空间复杂度

程序每做一次基本操作,开辟或访问的新的存储空间,因此空间总量和基本操作的次数同阶,又时间复杂度就是用基本操作的次数来描述的,故时间复杂度就是空间复杂度的上界

总结

对算法性能的度量主要采用时间复杂度来描述,不断的放大问题的边界来简化问题(采用最差情况,采用上界,采用操作次数来代替时间),得到最终的方法:就是看基础操作的次数,然后利用大O的性质(去掉常系数,去掉低此项)简化

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: