算法分析之【时间复杂度】

时间复杂度


当电脑运行下面这段代码的时候,执行任何一条语句都需要花费时间(为了方便讨论,这里我们把每一条语句的执行时间都看做是一样的,记为一个时间单元
在这里插入图片描述
这个程序有这么几个地方消耗了时间


蓝色框的两条语句,花费2个时间单元

② 黑色框的一条语句,花费n+1个时间单元

红色框的两条语句,花费2*n个时间单元


那么一共花费了3n+3个时间单元,可以看出,程序消耗的时间和n成线性关系

  • 用T(n)表示这个程序运行了多长时间,那么这个程序运行的时间就可以写成T(n)=3n+3。其中的n被我们称为问题的规模,其实就是处理的问题的大小

在这里插入图片描述
我们常常会对这个函数进行简化,使得它既简单又不失函数的主要特性
所以一般只关心随着问题规模n趋于无穷时函数中对函数结果影响最大的项,也就是最高次项

举个栗子:

  • T(n)=n+1 忽略常数项 :T(n)~n
  • T(n)=n+n2 忽略低阶项: T(n)~n2
  • T(n)=3n 忽略最高阶的系数: T(n)~n

至于判断哪个是高阶项,哪个是低阶项,只需记住下面的大小关系就行了,到时按照这个进行忽略(忽略相对较小的)

在这里插入图片描述
简化后的式子被称为这个程序算法的时间复杂度,记做O(f(n)),f(n)就是简化后的式子,比如说刚开始讨论的T(n)=3n+3,简化后T(n)~f(n)=n,那我们记为O(n)

时间复杂度可以表示某个算法的运行时间的趋势,大致地度量算法效率的好坏


时间复杂度的计算

计算时间复杂度大O的方法

一、得出运行时间的函数
二、对函数进行简化

  1. 常数1取代运行时间中所有加法常数
  2. 修改后的函数中,只保留最高阶项
  3. 如果最高阶项存在 且系数不为1,则忽略这个项的系数(即令其系数为1

举个栗子:

int n = 0;
n = n + 6;
printf(n);

T(n)=3(三条语句1+1+1),对这个函数进行简化,用常数1取代常数3,然后取代后的函数没有最高阶项,那么这个算法的时间复杂度就是O(1).
O(1)也被称为常数阶
如果每次都要把时间函数算出来,挺麻烦的,可以耍耍小聪明,一般来说,最内层执行次数最多的语句就决定了整个算法的趋势

for(int i = 0; i < n; i++)
	printf("哈");

这个内层打印语句需要循环n次,随着问题规模n的增加会呈线性增加,可以判定其时间复杂度为O(n)

按照这个方法就很容易得出下面这个嵌套的两层for循环的时间复杂度为O(n2)

for(int i = 0; i < n; i++) {
	for(int j = 0; j < n; j++) {
		cout << "平方阶" << endl;
	}
}

有一个很神奇的函数——对数函数,它随着自变量的增大,因变量增长的很慢
在这里插入图片描述
下面这段代码的复杂度就为对数级别O(logn)

int sum = 1;
while(sum < n) {
	sum = sum * 2;
}

和之前的分析方法一样,我们着重看执行次数最多的内层代码语句

sum = sum * 2;

每循环一次,sum就给自身乘以2,乘了多少次就跳出循环了呢(大于等于n)?不知道,就设为x吧,那么 2x=n,解出 x=log2n,这说明随着n的增大,最消耗时间的内层语句是呈对数变化的。

感谢阅读~


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值