时间复杂度与“大O记法”

“大O记法”:对于单调的整数函数f,如存在一个整数函数g和实常数c>0,使得对于充分大的n总有f(n) <c*g(n),就说函数g是f的一个渐近函数(忽略常数),记为f(n)=O(g(n))。也就是说,在趋向无穷的极限意义下,函数f的增长速度受到函数g的约束,也就是函数f和g的特征相似。
时间复杂度:假设存在函数g,使得算法A处理规模为n的问题示例所用时间为T(n)=O(g(n)),则称O(g(n))为算法A的渐近时间复杂度,简称时间复杂度,记为T(n)

如何理解“大O记法”

对于算法的时间性质和空间性质,最重要的是其数量级和趋势,这些是分析算法效率的主要部分。例如,可以认为3n2和100n2属于同一个量级,如果两个算法处理同样规模实例的代价分别为这两个函数,就认为他们的效率差不多,都为n2级。

最坏时间复杂度

分析算法时,存在几种可能的考虑:

  • 算法完成工作最少需要多少基本操作,即为最优时间复杂度
  • 算法完成工作最多需要多少基本操作,即为最坏时间复杂度
  • 算法完成工作平均需要多少基本操作,即为平均时间复杂度

最优时间复杂度,价值意义不大,反应出最乐观的最理想的情况,没有参考价值。
对于最坏时间复杂度,提供了一种保障,表明算法在此种诚度的基本操作中一定能完成工作。
对于平均时间复杂度,是对算法的一个全面评价,因此她完整全面的反映了这个算法的性质。
因此,我们主要关注算法的最坏情况,就是最坏时间复杂度。

时间复杂度的几条基本计算规则

  1. 基本操作,只有常数项,认为其时间复杂度为O(1)
  2. 顺序结构,时间复杂度按加法进行计算
  3. 循环结构,时间复杂度按乘法进行计算
  4. 分支结构,时间复杂度取最大值
  5. 判断一个算法的效率时,往往只需要关注操作数量的最高次项,其他次要项和常数项可以忽略
  6. 在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度
function mergesort(i,j){
    let m;
    if(i!=j){
        m = (i+j) / 2;
        mergesort(i,m);
        mergesort(m+1,j);
        merge(i,j,m); //this function time complexity is O(n);
    }
}
mergesort(1,n); //求该调用时间复杂度O(?)
设mergesort操作次数为f(n),merge复杂度为cn,则:
f(n)=2f(n/2)+2*c*n/2;
    =2(2f(n/4)+2*c*n/4)+cn;
    =2(2(2f(n/8)+2*c*n/8)+cn/2)+cn;
    =2^k*f(n/(2^k))+kcn; // 1,k为递归次数log2(n);
f(1)=c*1=c; // 2
由1,2式可知:
当n=2^k时,f(n)=c*n+c*n*log2(n);
故O(?) = O(nlog2(n));

岐山
1 声望1 粉丝

引用和评论

0 条评论