第一章 绪论(下)

本文探讨了算法效率的度量,通过大O记法分析了不同算法的时间复杂度,强调在评估算法性能时可以忽略低阶项和常数项。介绍了加法规则和乘法规则,并通过示例解释了如何简化表达式。此外,还提到在大量代码中,只需关注最深层循环的影响。最后,提到了递归调用对空间复杂度的影响。
摘要由CSDN通过智能技术生成

算法效率的度量

算法时间复杂度->T = T(n)

​ 事前预估算法时间开销T(n)与问题规模n的关系(T表示“time”)

//算法1——逐步递增型爱你
void loveYou(int n){	//n为问题规模
1	int i=1;			//爱你的程度
2   while(i<=n){
3       i++;			//每次加一
4       printf("I Love You %d\n",i);
    }
5   printf("I Love You More Than %d\n",n);
}
int main(){
    loveYou(3000);
}
语句频度:
1				——1次
2				——3001次
3,4				——3000次
5				——1次
T(3000) = 1 + 3001 + 2*3000 + 1
时间开销与问题规模n的关系:
T(n) = 3n+3

问题一:是否可以忽略表达式某些部分?

​ ——只考虑阶数,用大O记法表示

时间开销与问题规模n的关系:

  • T~1(n) = 3n +3
  • T~2(n) = n^2 + 3n+1000
  • T~3(n) = n^3 + n^2 + 99999999

结论:可以只考虑阶数高的部分,甚至可以将阶数高的系数忽略

大O表示“同阶”,同等数量级。即:当n->无穷时,二者之比为常数

  • T~1(n) = O(n)
  • T~2(n) = O(n^2)
  • T~3(n) = O(n^3)

T ( n ) = O ( f ( n ) ) < = > l i m ( n − > 无 穷 ) T ( n ) / f ( n ) = k T(n) = O(f(n))<=>lim(n->无穷) T(n)/f(n) = k T(n)=O(f(n))<=>lim(n>)T(n)/f(n)=k

  1. 加法规则:多项相加,只保留最高阶的项,且系数变成1
    T ( n ) = T 1 ( n ) + T 2 ( n ) = O ( f ( n ) ) + O ( g ( n ) ) = O ( m a x ( f ( n ) , g ( n ) ) ) T(n) = T1(n) + T2(n)=O(f(n))+O(g(n))=O(max(f(n),g(n))) T(n)=T1(n)+T2(n)=O(f(n))+O(g(n))=O(max(f(n),g(n)))

  2. 乘法规则:多项相乘,都保留
    T ( n ) = T 1 ( n ) ∗ T 2 ( n ) = O ( f ( n ) ) ∗ O ( g ( n ) ) = O ( f ( n ) ∗ g ( n ) ) T(n)=T1(n)*T2(n)=O(f(n))*O(g(n))=O(f(n)*g(n)) T(n)=T1(n)T2(n)=O(f(n))O(g(n))=O(f(n)g(n))
    Eg:T3(n)=n^3 + n^2log~2 n

    ​ =O(n^3) + O(n^2log~2 n)

    ​ =O(n^3)

结论:

O(1) < O(log~2 n) < O(n) < O(nlog~2 n) < O(n^2) < O(n^3) < O(n!) < O(n^n)

在这里插入图片描述

在这里插入图片描述

口诀:常对幂指阶

问题二:如果有好几千行代码,按这种方式需要一行一行数?

​ ——只需考虑最深层循环的循环次数与n的关系

//算法1——逐步递增型爱你
void loveYou(int n){	//n为问题规模
//插入1000行顺序执行的代码
1	int i=1;			//爱你的程度
2   while(i<=n){
3       i++;			//每次加一
4       printf("I Love You %d\n",i);
    }
5   printf("I Love You More Than %d\n",n);
}
int main(){
    loveYou(3000);
}

T(n) = 3n + 1003 = O(n)

结论1:顺序执行的代码只会影响常数项,可以忽略

结论2:只需要挑循环中的一个基本操作分析它的执行次数n的关系即可

//算法2——嵌套循环型爱你
void loveYou(int n){	
 	int i=1;			
    while(i<=n){		//外层循环执行n次
        i++;			
        printf("I Love You %d\n",i);
    	for(int j=1;j<=n;j++){//嵌套两层循环
            printf("I am Iron Man\n");//内层循环共执行n^2次
        }
    }
    printf("I Love You More Than %d\n",n);
}
int main(){
    loveYou(3000);
}

结论3:如果有多层嵌套循环,只需关注最深层循环循环了几次

T(n) = O(n) + O(n^2) = O(n^2)

小练习

在这里插入图片描述

在这里插入图片描述

算法的时间复杂度

最快时间复杂度:最快情况下算法的时间复杂度

平均时间复杂度所有输入实例等概率出现的情况下,算法的期望运行时间

最好时间复杂度:最好情况下算法的时间复杂度

总结

在这里插入图片描述

小故事:算法的性能问题只有在n很大时才会暴露出来

空间复杂度 S->Space

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

函数递归调用带来的内存开销

在这里插入图片描述

5:n=5,a,b,c

4:n=4,a,b,c

每一层假设为4*4B=16B 几位 kB

如果规模为n 则空间复杂度为nkB

在这里插入图片描述

总结:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值