算法复杂度分析

什么是数据结构和算法

数据结构就是指一组数据的存储结构,算法就是操作数据的一组方法。
数据结构是为算法服务的,算法要作用在特定的数据结构上。数据结构是静态的,它只是组织数据的一种方式。如果不在它的基础上操作、构建算法,孤立存在的数据结构就是没用的。

复杂度分析

数据结构和算法解决的是如何更省、更快地存储和处理数据的问题,因此,我们就需要一个考量效率和资源消耗的方法,这就是复杂度分析方法。
很多时候我们受限于环境和数据量,没有办法通过运行程序的方式,计算代码的执行时间和占用内存的大小,这时候我们需要一种可以不依赖数据,就能估算出算法执行效率的方法。

大O复杂度表示法

算法的执行时间与每行代码的执行次数成正比,用T(n) = O(f(n))表示,其中T(n)表示算法执行总时间,f(n)表示每行代码执行总次数,而n往往表示数据的规模。
大 O 时间复杂度并非指代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度(asymptotic time complexity),简称时间复杂度。公式中的低阶、常量、系数三部分并不左右增长趋势,所以都可以忽略。

时间复杂度

时间复杂度分析的方法:

  1. 只关注循环次数最多的一段代码
  2. 加法法则:总复杂度等于量级最大的那段代码的复杂度,比如有两段代码,一段代码复杂度是O(n),另一段代码是O(2^n),总复杂度就是 O(2^n)
  3. 乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积

常见的复杂度量级:
在这里插入图片描述
上述量级可以粗略分为,多项式量级和非多项式量级,其中非多项式量级的只有O(2^n) 和 O(n!)。
当n越来越大,非多项式量级的算法执行时间会急剧增加,所以它们是非常低效的方法。

多项式量级介绍:

  1. O(1):一般情况下,只要算法中不存在循环语句、递归语句,即使有成千上万行的代码,其时间复杂度也是Ο(1)
  2. O(logn)、O(nlogn):对数阶时间复杂度比较难分析,看下面一段代码
 i=1;
 while (i <= n)  {
   i = i * 2;
 }

i = i * 2 这行代码执行次数最多,所以只需要分析它的时间复杂度即可。从代码中可以看出,当 2^x = n 时结束循环, 计算 x=log2n,所以这段代码的时间复杂度就是 O(log2n)。

  1. O(m+n)、O(m*n):m 和 n 是表示两个数据规模。我们无法事先评估 m 和 n 谁的量级大,所以我们在表示复杂度的时候,就不能简单地利用加法法则,省略掉其中一个。所以,上面代码的时间复杂度就是 O(m+n)。
空间复杂度

空间复杂度全称就是渐进空间复杂度,表示算法的存储空间与数据规模之间的增长关系,通过下面一段代码分析空间复杂度

void print(int n) {
  int i = 0;
  int[] a = new int[n];
  for (i; i <n; ++i) {
    a[i] = i * i;
  }

  for (i = n-1; i >= 0; --i) {
    print out a[i]
  }
}

第 2 行代码int i = 0;,我们申请了一个空间存储变量 i,但是它是常量阶的,跟数据规模 n 没有关系,所以我们可以忽略。第 3 行 int[] a = new int[n] 申请了一个大小为 n 的 int 类型数组,除此之外,剩下的代码都没有占用更多的空间,所以整段代码的空间复杂度就是 O(n)。
我们常见的空间复杂度就是 O(1)、O(n)、O(n2 ),像 O(logn)、O(nlogn) 这样的对数阶复杂度平时都用不到。而且,空间复杂度分析比时间复杂度分析要简单很多。所以,对于空间复杂度,掌握刚我说的这些内容已经足够了。

参考:极客时间《数据结构与算法之美》课程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值