复杂度分析 效率与空间的消耗

为什么需要大O表示法?在对一个程序的好坏做评估时,改程序的时间和空间消耗是很重要的一个评估标准。当数据量增大时,程序运行的时间也会相应的增加,那么增长的幅度是呈指数还是以线性增长呢?这时就需要使用大O表示法来进行估算。

其中,还有一种叫时候统计法的检测方法,即实时监测代码,程序的运行时间和空间,这种方法较大程度受机器的环境和数据量影响,如内存,CPU的好坏,都会直接影响到运行时间的长短,故从便捷程度上来说,大O表示法还是较为舒服。

如下伪代码,估算他的运行时间。

 int cal(int n) {
     int sum = 0;
     int i = 1;
     int j = 1;
     for(; i <= n; i++) {
         j = 1;
         for(; j <= n; j++) {
             sum = sum + i + j;
         }
    }
 }

假设代码中每行代码的执行时间为t,则程序中第2~4行共执行了3t,程序5~6行执行了2nt,程序7~8行共执行了2n^2,所以这段代码执行花费了(2n^2 + 2n + 3)t

增长趋势如下图

其中,常数,低阶,系数并不影响这一趋势,故直接舍弃即可,于是只剩下了n^2,所以他的时间复杂度为O(n^2)。

一、对于分析时间复杂度有以下方法

1.关注运行次数最多的

 int cal(int n) {
     int sum = 0;
     int j = 1;
     for(; j <= n; j++) {
         sum = sum + j;
     }
 }

在以上伪代码中,第2~3行代码只运行了一次,所以无需关注,而第5行代码运行的次数与n的量级挂钩,所以时间复杂度为O(n).

2.加法法则:总复杂度等于量级最大的那段代码的复杂度

 int cal(int n) {
     int sum1 = 0;
     int j = 1;
     for(; j <= n; j++) {
         sum1 = sum1 + j;
     }
      
     int sum2 = 0
     int i = 1;
     for(; i <= 1000; i++) {
        sum2 = sum2 + i;
     }
 }

在以上代码代码中,第一段的复杂度为O(n),而第二段为常数,故可忽略不计。可遵循以下公式

T1(n) = O(f(n)),
T2(n) = O(g(n)),
Tn = T1(n) + T2(n) = max(O(f(n)), O(g(n))) = O(max(O(f(n)), O(g(n))));

3.乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积

 int cal(int n) {
     int res= 0;
     int j = 1;
     for(; j <= n; j++) {
         res = res + k(j);
     }
 }

 int k(int n) {
    int sum = 0;
    int j = 1;
    for(; j <= n; j++) {
        sum = sum + j;
    }
    result sum;
 }

我们先来看k()的复杂度,很明显,为O(n)。再来看cal的复杂度,很明显,这里出现了嵌套代码,在第五行中调用了k()。在不调用k的情况下,cal()的复杂度为O(n),调用后则使用乘积的形式,则复杂度为O(n * n) = O(n^2)。可遵循以下公式。

Tn = T1(n) * T2(n) = O(n * n) = O(n ^ 2)

 

二、常见的复杂度量级

多项式量级如下

  • 常数阶 O(1)
  • 对数阶 O(log n)
  • 线性阶 O(n)
  • 线性对数阶 O(nlog n)
  • 次方阶 平方阶 O(n ^ 2) 立方阶 (n ^ 3) k次方阶(n ^ k)

非多项式量级如下

  • 指数阶 O(2 ^ n)
  • 阶乘阶 O(n!)

出现两个量级数时如下

  • O(m + n)
  • O(n * m)

 

今天先写这么多,有问题欢迎评论。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值