算法与数据结构(2)- 算法的复杂度

时间复杂度T(n)与“大O记法”

我们假定计算机执行算法每一个基本操作的时间是固定的一个时间单位,那么有多少个基本操作就代表会花费多少时间单位。显然对于不同的机器环境而言,确切的单位时间是不同的,但是对于算法进行多少个基本操作(即花费多少时间单位)在规模数量级上却是相同的,由此可以忽略机器环境的影响而客观的反应算法的时间效率。

对于算法的时间效率,我们可以用“大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)
在这里插入图片描述
上面算法中,我们运算时间值 为 T = 1000* 1000 * 1000 * 10

在这里插入图片描述
以上算法中,我们运算时间值 为 T = 1000* 1000 * 10

但是,如果我们将for循环的1000变为2000, 这个 T 就不能代表上面算法的时间值了。

算法是一种思想,是解决通用类问题的一种方式,所以上面 T去衡量一种算法,本来1000就是固定的数值,把1000换成2000,算法还是那个算法, 就却不能用上面T去衡量同一种算法的时间效率,显然是不可行的。

所以我们吧1000换成n 那么上面变为 T = 10 * n^3 和 T = 10* n^2

时间复杂度一般用T(n)表示 T(n) = 10 * n^3 和 T(n) = 10 * n^2

大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记法”

对于算法进行特别具体的细致分析虽然很好,但在实践中的实际价值有限。对于算法的时间性质和空间性质,最重要的是其数量级和趋势,这些是分析算法效率的主要部分。而计量算法基本操作数量的规模函数中那些常量因子可以忽略不计。例如,可以认为3 *n2**和**100*n2属于同一个量级,如果两个算法处理同样规模实例的代价分别为这两个函数,就认为它们的效率“差不多”,都为n2级

所以,当我们衡量一个算法的时间效率问题 ,应该保留公式的最特种最核心的部分,然后用大O括起来表示

所以最终的时间复杂度表示法为
T(n) = O(n^3)

T(n) = O(n^2)

最坏时间复杂度

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

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

对于最优时间复杂度,其价值不大,因为它没有提供什么有用信息,其反映的只是最乐观最理想的情况,没有参考价值。

对于最坏时间复杂度,提供了一种保证,表明算法在此种程度的基本操作中一定能完成工作。

对于平均时间复杂度,是对算法的一个全面评价,因此它完整全面的反映了这个算法的性质。但另一方面,这种衡量并没有保证,不是每个计算都能在这个基本操作内完成。而且,对于平均情况的计算,也会因为应用算法的实例分布可能并不均匀而难以计算。

因此,我们主要关注算法的最坏情况,亦即最坏时间复杂度。

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

  1. 基本操作,即只有常数项,认为其时间复杂度为O(1)
    例如:

     if a**2 + b**2 == c**2 and a+b+c == 1000:
                print("a, b, c: %d, %d, %d" % (a, b, c))
    

    上面 if 后面是常数操作,这里我们就认为其时间复杂度为O(1)

  2. 顺序结构,时间复杂度按加法进行计算
    如果代码执行为由上而下的执行,那么我们计算其时间复杂度是从上而下累加

  3. 循环结构,时间复杂度按乘法进行计算

  4. 分支结构,时间复杂度取最大值

  5. 判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略
    例如 T(n) = 4n^3 + 2n^2 + 100
    上面这个公式中,2n^2100 俩个就可以忽略掉,4n^3中的4也忽略,那么最终的时间复杂度为T(n) = O(n^3)

  6. 没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度

常见时间复杂度

执行次数函数举例非正式术语
12O(1)常数阶
2n+3O(n)线性阶
3n2 + 2n +1O(n2)平方阶
5log2n + 20O(logn)对数阶
2n + 3nlog22 +19O(nlogn)nlogn阶
6n3 + 2n2 +3n+4O(n3)立方阶
2nO(2n)指数阶

注意,经常将log2n(以2为底的对数)简写成logn
在这里插入图片描述
所消耗的时间从小到大
O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)

空间复杂度S(n)

类似于时间复杂度的讨论,一个算法的**空间复杂度S(n)**定义为该算法所耗费的存储空间,它也是问题规模n的函数。

渐近空间复杂度也常常简称为空间复杂度。

空间复杂度(SpaceComplexity)是对一个算法在运行过程中临时占用存储空间大小的量度。

算法的时间复杂度和空间复杂度合称为算法的复杂度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值