数据结构(二):算法复杂度

算法时间复杂度

函数渐近增长

算法中执行次数最多的那条语句就是基本语句,测定运行时间就是计算基本语句的执行次数

  1. 可以忽略加法常数
  2. 与最高此项相乘的常数并不重要
  3. 最高次项的指数越大,增长越快
  4. 判断一个算法执行效率时,函数中的常数和其他次要项常常可以忽略,更应该关注主项(最高阶项)的阶数
  5. 某个算法,随着n增大,它会越来越优于另一算法,或者越来越差与另一算法。

大O表示法

我们一般使用O(f(n))来体现算法的复杂度。

推导大O阶的方法
  1. 用常数1取代运行时间中的所有加法常数
  2. 在修改后的运行次数函数中,只保留最高阶项
  3. 如果最高阶项存在并且不是1,则去除与这个项相乘的常数。

得到的结果就是大O阶

常数阶
int sum = 0,n = 100; //执行一次  
sum = (1+n)*n/2; //执行一次  
printf("%d",sum); //执行一次 

上面算法的运行的次数的函数为f(n)=3,根据推导大O阶的规则1,我们需要将常数3改为1,则这个算法的时间复杂度为O(1)。如果sum = (1+n)*n/2这条语句再执行10遍,因为这与问题大小n的值并没有关系,所以这个算法的时间复杂度仍旧是O(1),我们可以称之为常数阶。

线性阶

线性阶主要分析循环结构的运行情况

for(int i=0;i<n;i++){
//时间复杂度为O(1)的算法...}

上面算法循环体中的代码执行了n次,因此时间复杂度为O(n)。

对数阶
int number=1;
while(number<n)
{number=number*2}

可以看出上面的代码,随着number每次乘以2后,都会越来越接近n,当number不小于n时就会退出循环。假设循环的次数为X,则由2^x=n得出x=log₂n,因此得出这个算法的时间复杂度为O(logn)。

平方阶
//嵌套循环
for(int i=0;i<n;i++){   
     for(int j=0;j<n;i++){
        //复杂度为O(1)的算法         ... 
     }
 }

内层循环的时间复杂度在讲到线性阶时就已经得知是O(n),现在经过外层循环n次,那么这段算法的时间复杂度则为O(n²)。

常用的时间复杂度按照耗费的时间从小到大依次是:
O(1)<O(logn)<O(n)<O(nlogn)<O(n²)<O(n³)<O(2ⁿ)<O(n!)

在这里插入图片描述

像O(n³),过大的n都会使得结果变得不现实。同样指数阶O(2ⁿ)和阶乘阶O(n!)的等,除非是很小的n值,否则哪怕n只是100,都是噩梦般的运行时间。这种不切实际的算法复杂度,一般我们都不会去讨论它。
——《大话数据结构》

最坏情况和平均情况
  • 举个例子,在查找遍历的时候,有可能在位置1就找到了,这是最好的情况;也有可能到n才能找到,这是最坏情况。
  • 平均运行时间是以上例子的n/2,平均运行时间是最有意义的,因为他是期望的运行时间。
  • 一般在没有特殊说明的情况下,计算算法时间复杂度都是指最坏时间复杂度

算法空间复杂度

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

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

一个算法在计算机存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面。算法的输入输出数据所占用的存储空间是由要解决的问题决定的,是通过参数表由调用函数传递而来的,它不随本算法的不同而改变。

存储算法本身所占用的存储空间与算法书写的长短成正比,要压缩这方面的存储空间,就必须编写出较短的算法。

如当一个算法的空间复杂度为一个常量,即不随被处理数据量n的大小而改变时,可表示为O(1);当一个算法的空间复杂度与以2为底的n的对数成正比时,可表示为0(10g2n);当一个算法的空I司复杂度与n成线性比例关系时,可表示为0(n).若形参为数组,则只需要为它分配一个存储由实参传送来的一个地址指针的空间,即一个机器字长空间;若形参为引用方式,则也只需要为其分配存储一个地址的空间,用它来存储对应实参变量的地址,以便由系统自动引用实参变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值