浅谈时间复杂度
算法时间复杂度
存在什么问题?
• 和机器性能有关,如:超级计算机 v.s. 单片机
• 和编程语言有关,越高级的语言执行效率越低
• 和编译程序产生的机器指令质量有关
• 有些算法是不能事后再统计的,如:导弹控制算法
能否排除与算法本身无关的外界因素?
时间复杂度分析主要关注算法本身的执行效率,它排除了与算法无关的外界因素,如硬件性能、操作系统等。这种分析提供了一种理论上的性能评估,帮助我们预测算法在不同输入规模下的表现。
能否事先估计?
时间复杂度分析允许我们在实现算法之前,通过数学模型和逻辑推理来预测算法的大致性能。这种预测基于算法的逻辑结构,而不是实际的执行环境,因此它提供了一种在算法设计和选择阶段非常有用的指导。
事前预估算法时间开销为T(n)与问题规模n的关系
- 引入例子:逐步递增型爱你
void loveyou(int n){//n为问题规模
① int i=1;
②while(i<=n){
③i++;//每次+1
④printf("I Love You%d\n",i);
}
⑤ printf("I Love You More Than %d\n",n);
int main(){
love you (3000);
}
语句频度:
① ——1次
② ——3001次
③④ ——3000次
⑤ ——1次
T(3000) = 1 + 3001 + 2*3000 + 1
时间开销与问题规模 n 的关系:
T(n)=3n+3
问题1:是否可以忽略表达式某些部分?
只考虑阶数,用大O记法表示
问题2:如果有好几千行代码,按这种方法需要一行一行数?
只需考虑最深层循环的循环次数与 n 的关系
结论1:可以只考虑阶数高的部分
结论2:问题规模足够大时,常数项系数也可以忽略
T1(n) = O(n)
T2(n) = O(n2)
T3(n) = O(n3)
结论3:如果有多层嵌套循环,只需关注最深层循环循环了几次
a)加法规则(多项相加,只保留最高的项,且系数变为1
T(n) = T1(n) + T2(n) = O(f(n)) + O(g(n)) = O(max(f(n), g(n)))
b)乘法规则 (多项相乘,都保留)
T(n) = T1(n)×T2(n) = O(f(n))×O(g(n)) = O(f(n)×g(n))
Eg:T3(n)= n3 + n2 log2n
= O(n3) + O(n2 log2n)
= ???
时间复杂度大小:
O(1) < O(log2n) < O(n) < O(nlog2n) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)
两个时间复杂度的大小比较:即是哪个的阶数更高(时间复杂度更高)
以O(log2n) < O(n)为例,当n足够大时,O(log2n)趋向于无穷大时比上 O(n)趋向于无穷大时的比阶,利用洛必达法则,极限为0,即n比log2n变大的速度快很多
记忆口诀:常对幂指阶
小练习
三种复杂度
最坏时间复杂度:最坏情况下算法的时间复杂度
平均时间复杂度:所有输入示例等概率出现的情况下,算法的期望运行时间
最好时间复杂度:最好情况下算法的时间复杂度
时间复杂度学习小结
时间复杂度是评估算法效率的关键指标,它帮助我们了解算法执行时间如何随输入数据量变化。通过分析算法的基本操作和执行次数,我们可以预测算法在不同情况下的性能表现,从而在实际应用中做出更合理的选择和优化。