复杂度

作者: Tlion | 来源:发表于2019-02-18 20:59 被阅读0次

算法的五要素


  1. 输入、输出
  2. 可行性
  3. 正确性
  4. 确定性
  5. 有穷性

时间复杂度


为了测试算法的运行效率,我们可以在机器上跑一些测试数据,来测试算法具体执行时间的快慢,这叫做 事后统计法,但是, 事后统计法有下面两个缺点:

  1. 执行效率受到 运行环境 的影响,两台不同的机器可能的到相反的结果
  2. 执行效率受到输入的 测试数据规模 的影响

所以,为了发现 数据规模运行效率 之间的关系,引入了 复杂度分析

渐进时间复杂度分析

所谓渐进时间复杂度,即为表示 算法执行时间效率与输入规模 n 增长时的趋势,使用函数来描述 n 增长时,运行效率的变化趋势。

使用大 O 记号来表示时间复杂度:
如果存在 f(n),使得在 n >> 2 的情况下,时间复杂度 T(n) <= Cf(n),则时间复杂度可以表示为 O(f(n))

O 记号有如下特点:

  1. f(n) 函数的 常数项低次幂项 可以省略(应为在 n 具有相当规模时,这些对高次幂的影响不大)
  2. 若 T(n) = T1(n) + T2(n),则 T(n) = O( max( f(n), g(n) ) )
  3. 若 T(n) = T1(n) * T2(n),则 T(n) = O( f(n)*g(n) )
  4. 若有两个输入时, 若 T(n) = T1(n) + T2(m),则 T(n) = O( f(n) + g(m) )
  5. 若有两个输入时,若 T(n) = T1(n) * T2(m),则 T(n) = O( f(n)*g(m) )

分类

时间复杂度分为:

  1. 最好情况时间复杂度
  2. 最坏情况时间复杂度
  3. 平均时间复杂度
  4. 均摊时间复杂度

一般说复杂度时,基本考虑 最坏情况时间复杂度

常见时间复杂度

对于时间复杂度,基本可以分为两类,多项式量级非多项式量级,而 非多项式量级 有两个:O(2n)、O(n!)

常见时间复杂度:

  1. 常量阶: O( 1 )
  2. 对数阶: O( log(n) )
  3. 线性阶: O( n )
  4. 线性对数阶: O( nlog(n) )
  5. 幂次阶: O( nk ) (k = 2,3,4...)

O(1)

O(1) 不是指只有一条语句执行,而是只要执行的语句是确定个数的,和输入规模 n 没有关系的,都是 O(1) 复杂度

一般来讲,只要代码中没有 循环递归,基本都是 O(1) 复杂度的

O(n)、O(nlog(n))

对数阶复杂度比较常见,也是比较难分析的
例:

let i = 0;
let sum = 0;
while(i < n){
  sum += i;
  i += 2;
}

上面这段代码,i 每次都加 2,所以最后等于 n 的时候, 2x = n,所以 x = log2n,由于底数之间可以互相转化,所以忽略底数,记做 log(n)

O( nlog(n) ) 则是相当于把 O( log(n) )的算法执行了 n 次,根据大 O 记号的乘法原理,则复杂度就为 O( nlog(n) )

空间复杂度

空间复杂度指的是,算法运行过程中新申请的空间占用,算法必须使用的空间占用不计入其中

时间复杂度例子

1. O(1)

// 从 n >= 3 的数组中找一个非最大、最小数
// 解决该问题一共有三步
// 1. 选取任意数组中三个数
// 2. 对选取的数进行排序
// 3. 输出排序结果的第二个数

这里的执行时间和 n 无关,只限于有限步骤,所以时间复杂度为 O(1)

2. O( log(n) )

// 输出给定非负整数的二进制的 1 的个数
function count(n){
  let count = 0;
  while(n!=0){
    sum += n & 1;
    n >>= 1;
  }
}

使用 右移运算符,n 每次都减少一半,所以有: 2x = n,x = log(n),所以一共执行了 1 + x 轮循环,所以时间复杂度为 O( log(n) )

3. O( n )

// 计算数组和
function sum(arr){
  let sum = 0;
  for(let i=0; i<arr.length; i++){
    sum += arr[i];
  }
}

计算和的时候,根据数组长度 n,一共执行了 n 次加法操作,所以时间复杂度为 O( n )

4. O( nlog( n ) )

// 归并排序
function mergeSort(arr){
  if(arr.length === 1){
    return arr;
  }
  mergeSort(left, middle);
  mergeSort(middle+1, right);
  merge(left, middle, right);
}

分析1:
根据代码得出时间复杂度公式:T(n) = 2*T(n/2) + O(n),T(1) = O(1),则推出 T(n) = nO(1) + n/2*O(2) + n/4*O(4) + ... + 2*O(n/2) + O(n),其中个数为 log(n) 个,所以时间复杂度为 O( nlog( n ) )

分析2:
递归一共生成了 n + n/2 + n/4 + ... + 1 个递归实例,其中个数为 log(n) 个,所以总个数为 C*nlog(n),所以时间复杂度为 O( nlog( n ) )

相关文章

  • 时间复杂度(下)

    时间复杂度知识点 最好时间复杂度 最坏时间复杂度 平均情况复杂度 均摊时间复杂度

  • 复杂度分析

    为什么需要复杂度分析? 大O复杂度表示法 时间复杂度分析 常见复杂度量级 复杂度量级简单说明 空间复杂度 时间复杂...

  • 复杂度分析笔记

    常见复杂度 :常数复杂度 :对数复杂度 :线性时间复杂度 :线性对数复杂度 :平方阶 :立方 :K次方阶 :指数阶...

  • 常用的排序算法

    插入排序 复杂度 思路 希尔排序 复杂度 思路 选择排序 复杂度 思路 归并排序 复杂度 思路 快速排序复杂度 思...

  • NLP初学之-算法复杂度

    算法的复杂度分为:时间复杂度和空间复杂度。

  • 算法基础知识

    算法的复杂度 算法的复杂度: 算法的时间复杂度和空间复杂度合称为算法的复杂度,一般不特别说明,讨论的时间复杂度均是...

  • 数据结构-0-时间复杂度和空间复杂度

    1. 算法的复杂度: 算法的复杂度分为时间复杂度和空间复杂度。时间复杂度,是衡量算法执行时间的长度;空间复杂度,是...

  • 时间复杂度和空间复杂度笔记

    复杂度分析笔记 复杂度主要分为时间和空间复杂度 时间复杂度:算法(程序)执行的时间变化趋势 空间复杂度:算法(程序...

  • 算法复杂度

    算法的复杂度是以什么来度量的? 算法的复杂度是以时间复杂度和空间复杂度来计算的。 ①算法的时间复杂度 ...

  • sort_algorithm

    排序方法 时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性 复...

网友评论

      本文标题:复杂度

      本文链接:https://www.haomeiwen.com/subject/fydzeqtx.html