算法的复杂度度量--时间复杂度以及空间复杂度
数据结构和算法课程上都有关于时间复杂度的分析,但是自己一直都是一知半解,似乎懂却又不能解释清楚。希望这篇博客作为自己记录成长的开端!
为什么要有时间复杂度以及空间复杂度
评价一个算法有几大标准,主要包括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的性质(去掉常系数,去掉低此项)简化
阅读更多- 数据结构-算法效率的度量-时间复杂度和空间复杂度
- 排序算法的C语言实现以及各个算法的时间复杂度和空间复杂度分析(冒泡排序)
- 算法——时间复杂度和空间复杂度
- 算法第一弹:时间复杂度和空间复杂度
- 算法-时间复杂度和空间复杂度
- 常用的算法时间复杂度和空间复杂度
- 数据结构2:算法时间复杂度和空间复杂度的计算
- 算法-时间复杂度和空间复杂度
- 数据结构和算法-时间复杂度和空间复杂度
- 试设计一个算法,将数组A(0..n-1)中的元素循环右移k位,并要求空间复杂度为O(1),时间复杂度为O(n)。
- JAVA数据结构和算法:第一章(时间复杂度和空间复杂度)
- 《编程之美》中买书问题算法。空间复杂度O(n),时间复杂度O(n),求挑战
- 数据结构--算法(时间复杂度和空间复杂度)
- 第一章作业2-算法时间复杂度和空间复杂度
- 数据挖掘算法的空间复杂度与时间复杂度分析
- 算法时间复杂度和空间复杂度计算
- 常用算法时间复杂度和空间复杂度表
- 时间复杂度和空间复杂度2 - 数据结构和算法04
- 掌握算法的渐近时间复杂度和空间复杂度的意义与作用
- php算法基础----时间复杂度和空间复杂度