计算程序的时间复杂度和空间复杂度

理解程序执行的时间复杂度和空间复杂度对于优化程序非常重要
本篇文章重点分析如何计算一个程序的时间复杂度空间复杂度
一、时间复杂度
对涉及的对数时间复杂度写法的说明:
平时我们计算时间复杂度常说的logn以及nlog都没有涉及底数,这是因为无论是以e为底,还是以某个常数为底,底数始终是一个常数,在计算时间复杂度时常数可以忽略,因此,习惯性的写为logn、nlogn等等。
概念
执行算法所需要消耗的时间长短,称为算法的时间复杂度。
时间复杂度的表示方式(大O)
T(n)=O(f(n))
n是影响复杂度变化的因子,f(n)是复杂度具体的算法。
常见的时间复杂度量级(从小到大)
常数阶:O(1);
对数阶:O(logn)
线性阶:O(n);
线性对数阶:O(nlogn)
平方阶:O(n2)
立方阶:O(n3)
k次方阶:O(nk)
指数阶:O(2n)
阶乘阶:O(n!)
下面为了方便理解这些阶数的大小,给出博客(https://www.cnblogs.com/chenjinxinlove/p/10038919.html)
中绘制的时间复杂度曲线以及性能比较。
在这里插入图片描述
在这里插入图片描述
举例分析
常数阶

int x=1;
int y=7;
y=x;

时间复杂度表示的是代码执行时间的一个增长变化趋势,在上面的代码中无论出现多少个赋值语句,其时间复杂度仍为O(1)。这是由于赋值操作本身没有增长趋势。
对数阶

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

对于上面的代码,假设n=16,则循环实际上一共执行4次,24=16,log216=4。所以时间复杂度为O(logn),至于为什么不写成O(lon2n),在文章的开头已经说明,这里不再赘述。
线性阶

int i=0;
int j=0;
while(i<n){
	i++;
	j++;
}

利用上面的代码顺便解决一个疑惑,
为什么时间复杂度都是统一的形式,不需要加常数项或者倍数
对于上述第1、2行代码,各执行一次;第三行代码执行1次;第4、5行代码各执行n次,加起来整个程序一共执行了2n+3次,那时间复杂度是不是直接写O(2n+3)就好了??
开始我也这么觉得,但是本文章上面提到,时间复杂度表示的是时间增长的一个趋势,占据算法运行时间长短的是它的增长趋势,1表示常数阶,n表示线性阶等等,因此没有~~O(2n+3)~~这种写法,只有O(n),统一写为O(n)也可以更好地区分,只要时间复杂度都为O(n),除去最好和最坏的时间,其算法的运行时间在一个数量级上,相差不会太大。
线性对数阶

int i=0;
int j=1;
while(i<n){
	while(j<n){
		j*=2;
	}
	i++;
}

上面算法有两层循环,最外层执行n次,里面一层执行logn次,因此算法事件复杂度为O(nlogn)。这两个算法的代码在上面都分析过,只不过在此进行嵌套。
平方阶

int i=0;
int j=0;
while(i<n){
	while(j<n){
		j++;
	}
	i++;
}

对于上面已经提到的线性阶O(n),两个线性阶进行嵌套,得到的就是平方阶,当然两层循环不一定都用n表示,改成m也是平方阶。趋势!趋势!趋势!很重要。
立方阶、k次方阶,在这里不再举例,就是对线性阶的多层嵌套
对于后面的指数阶阶乘阶在这里不好给出例子(我没找到合适的简单概括这两个例子的代码),恳请各位大神在评论区补充,我看到后一定立马补充进来,谢谢你们。
二、空间复杂度
概念
算法执行所需要消耗的存储空间的大小,称为算法的空间复杂度
空间复杂度主要包含三个方面:
1.程序本身所占空间
2.输入数据所占空间;
3.辅助变量所占空间
这个空间复杂度的理解可以对比时间复杂度来理解和计算
空间复杂度的表示方式(大O)
S(n)=O(g(n))
n表示问题规模
举例分析
常数阶

int i=0;
int j=0;
int sum=0;
i+=100;
j-=1000;
sum=i+j;

对上面的代码分析可知,代码中所需要的临时空间不会随着某个变量的改变而增加存储空间,因此算法的空间复杂度是一个常数阶O(1)。
线性阶

vector<int> vec=(n,1);
for(int i=0;i<n;i++)vec.push_back(i);

对于上面的代码,第1行是定义并初始化一个一维向量,向量大小所占的空间为n个int类型的空间,第2行,是对定义的一维向量进行赋值操作,执行了n次,但是没有产生新的空间,所以空间复杂度:S(n)=O(n),时间复杂度T(n)=O(n)。
三、总结
对于时间复杂度和空间复杂度在小的程序计算中难以察觉,毕竟现在的笔记本和台式CPU的计算能力大大提高,但是当某些数据量变大或者算法较为复杂时,根据时间复杂度和空间复杂度对算法进行优化,对整个算法的执行效率会有质的增长。本人有一篇博客中讲到了归并排序,是一个算法题目,在那个题目中如果不对算法进行选择时,法算执行会占用大量的内存、耗费较多的运行时间,有兴趣的可以去看一下。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是小峰呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值