怎样分析算法的复杂度

  • 前言

     当我们在利用算法实现解决某一个问题时,如果这个算法是正确的,那么通常要去思考这个算法需要的时间和空间资源是多少的问题,如果一个算法需要的时间很长,那么这种算法实际上就很难有用处,同样的如果一个需要很大内存的算法在实际中也是不能使用的。


一、什么是好的算法?

这里我们要明确一点:好的算法更优的算法 不能混为一谈;一个更优的算法消耗更少的时间、更少的空间,而我们作为初学者,应该更多的去考虑怎么写出一个好的算法,而所谓好的算法要满足这两个性质:

  • 1、准确性(任何情况下能彻底解决这个问题)需要对真实数据的大量测试;
  • 2、健壮性 编写的程序在任何情况下都不能崩溃 也要大量测试; 

不过事实上我们并没有那么多的数据量,并且用大量数据去测试是一个很烧钱的事情,我们现阶段能做到的,就是再给定的条件下,尽肯能多的解决问题的每一种情况,只有当我们写的程序能够保证解决给定的问题之后,我们会才要去考虑程序的效率

二、什么是效率?

我们说了,一个更优的算法就是在好的算法的之上提高了效率:我们习惯用时间复杂度和空间复杂度来描述这个“效率”;而所谓时间复杂度就是一个程序运行时间;空间复杂度就是程序占用的内存大小

三、关于复杂度

关于复杂度的分析,我们可以从理论上和实际来分析;从实际上分析就需要大量的数据去测试,对于现在的我们来说,更需要掌握的是从理论上来分析,也就是事前评估法:不需要数据又能大概的评估出时间复杂度和空间复杂度:

  • 时间复杂度:时间(语句)频度T(n) 与语句的(计算)执行次数成正比,n就是问题的规模,找到T(n)随着问题规模n变化的规律就是时间复杂度;
  • 空间复杂度:算法当中所占用的临时存储空间大小(也就是额外需要的空间);

现在的设备在一般问题上空间占用绰绰有余,也就是说在一般情况下,我们更加注重的是时间复杂度而不是空间,也就有以空间换时间的思想

主流上有四种角度来分析时间复杂度: 最好 、最坏 、平均 、摊均。其中最好和最坏都是在理想状态下的情况;

  • 最好:比如说要查找的元素恰好在第一个;
  • 最坏:比如说要查找的元素恰好在最后一个;

虽然最好和最坏都是极端情况,但对于我们而言也是有参考价值的;最好的意义就是让我们在设计算法时尽可能的接近最好(如KMP算法);而最坏的意义就不用多说了,我们平所说的时间复杂就是在最坏的情况下的分析;

  • 平均就是求加权平均值,公式中,第一个n表示最后能找到的状态,第二个n表示永远都找不到的状态;

\frac{(1+2+3+...+n)+n}{n+1}

  •  至于摊均,这里我们暂时不做描述;

四、分析复杂度的方法

我们通常用大O法来表示算法的时间性能T(n) = O(f(n)),而在用大O法的时候我们只需要关心数量级的最高次幂,即眼光放在增长率上面(就是高数中极限的思想;

 对fn的分析我们只需要遵照下面的原则一步步分析就可以了: 

  1. 对于循环结构,其主要运行时间在迭代中,只要找出算法中的基本语句(算法中执行次数最多的那一条语句) 通常是最内层循环的循环体;
  2. 对于顺序结构,大O法求和法则是找最大值;
  3. 对于选择结构 主要耗费时间就是在else/then语句上; 在算法的角度上,不细分的去看依旧看成O(1);
  4. 对于一些简单的输入输出和赋值,近似认为是O(1);
  5. 对于复杂的算法,把它拆分成能计算的部分,用大O的加法和乘法法则去算;

空间复杂度没什么可以多说的,只要记住空间复杂度是指额外的空间就行了;

你可能感兴趣的:(数据结构与算法,算法,数据结构)