复杂度分析

复杂度分析 是整个算法学习的精髓,只要掌握了它,数据结构和算法的内容基本上就掌握了一半。

为什么需要复杂度分析

因为事后统计法,测试的结果非常依赖测试环境,受数据规模的影响很大
所以我们需要一个不用具体的测试数据来测试,就可以粗略地估算计算法的执行效率的方法。

时间、空间复杂度分析方法

大 O 复杂度表示法

算法的执行效率,粗略地讲,就是算法代码执行的时间。
从 CPU 的角度来看,,每一行代码都执行着类似的操作:读数据-运算-写数据。尽管每行代码对应的 CPU 执行的个数、执行的时间都不一样。但是,我们这里只是粗略估计,所以可以假设每行代码执行的时间都一样,为 unit_time(单位时间)。

所有代码的执行时间 T(n)与每行代码的执行次数成正比。
执行多少次


T(n) = O(f(n))

大 O 时间复杂度实际上并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度(asymptotic time complexity),简称时间复杂度

时间复杂度分析

忽略低阶、常量、系数

  • 只关注循环执行次数最多的一段代码

  • 加法法则:总复杂度等于量级最大的那段代码的复杂度

function cal(n) {
  for (let i = 0, l = 100; i < l; i++) {
    console.log(i);
  }

  for (let i = 0; i < n; i++) {
    console.log(i);
  }

  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {}
  }
}

T(n) = O(max(fn(n),g(n)))
  • 乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积

function cal(n){
    for(let i=0;i<n;i++){
        foo(i)
    }
}

function foo(n){
    for(let i=0,i< n;i++){
        console.log(i)
    }
}

T(n) = T1(n) * T2(n) = O(n*n) = O(n2)。

常见时间复杂度分析

  • 常量阶\(O(1)\)

  • 对数阶\(O(logn)\)

  • 线性阶\(O(n)\)

  • 线性对数阶\(O(n)\)

  • 平方阶\(O(n^2)\) 、 立方阶\(O(n^3)\cdots\) k 次方阶\(O(n^k)\)

  • 指数阶\(O(2^n)\)

  • 阶乘阶\(O(n!)\)

对于复杂度量级,可以粗略分为两类,多项式量级和非多项式量级。其中非多项式量级只有两个\(O(2^n)\)\(O(n!)\)

最好、最坏、平均、均摊情况时间复杂度

最好情况时间复杂度(best case time complexity)

在理想的情况下,执行这段代码的时间复杂度

最坏情况时间复杂度(worst case time complexity)

在最糟糕的情况下,执行这段代码的时间复杂度

平均情况时间复杂度(average case time complexity)

均摊时间复杂度(amortized time complexity)

对一个数据结构进行一组连续操作中,大部分情况下时间复杂度都很低,只有个别情况下时间复杂度比较高,而且这些操作之间存在前后连贯的时序关系,这个时候,我们就可以将这一组操作放在一块儿分析,看是否能将较高时间复杂度那次操作的耗时,平摊到其他那些时间复杂度比较低的操作上。而且,在能够应用均摊时间复杂度分析的场合,一般均摊时间复杂度就等于最好情况时间复杂度。

数学知识

对数

换底公式

数列

等差数列

概率

概率乘法

posted @ 2021-03-15 07:58  Khadron  阅读(110)  评论(0编辑  收藏  举报