分析、统计算法的执行效率和资源消耗

分析、统计算法的执行效率和资源消耗

复杂度分析是整个算法学习的精髓,只要掌握了它,数据结构和算法的内容基本上就掌握了一半。
为啥需要复杂度分析?
其实我们把代码用电脑跑一遍我们可以知道这段代码用的内存和时间消耗,那么为啥还要进行复杂度分析呢?
1.测试结果和环境本身有很大的关系,比如拿个i3的电脑和i7的电脑测试,结果可想而知。
2.测试结果和测试数据息息相关,比如说排序,一个有序度很高的数列和一个有序度低的数列,肯定是低的快,如果测试数据规模太小,测试结果可能无法真实地反应算法的性能。
3.没3了。
所以说我们需要一种方法,能够不用具体的测试数据就能估算出它的效率。

大 O 复杂度表示法
下面这段代码是一个简单计算累加的代码

int leijia(int n)
{
	int sum=0;
	int i=1;
	for(;i<=n;i++)
	{
		sum+=i;
	}
	return sum;
}

定义单位时间为t
所以第三四行代码各需要1t,第5和7行代码都要运行n次,所以需要2n t的时间
所以这段代码需要的时间就是(2
n+2) t 。
所有代码的执行时间 T(n) 与每行代码的执行次数成正比

继续这样分析,我们看看下一段代码

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

我们依旧假设每个语句的执行时间是t。那这段的总执行时间T(n)是多少呢?
第3,4,5行代码消耗时间都是t。第6,8行代码都执行了n次,第9,11行代码都执行了n2(n的2次方)次。
所以这段代码的总执行时间是T(n)=(3+2n+2n2) t。
虽然我们不知道t的具体值是多少,但是通过这两段代码我们知道了 所有代码的执行时间 T(n) 与每行代码的执行次数 n 成正比

所以我们可以把这个规律写成公式
在这里插入图片描述
这里T(n)表示代码的执行时间,n表示数据规模大小,f(n)表示每行代码的次数总和,O表示T(n)和f(n)的,正比关系,所以,第一个例子中的 T(n) = O(2n+2),二个例子中的 T(n) = O(2n2+2n+3),这就是大 O 时间复杂度表示法。表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度。当 n 很大时,你可以把它想象成 10000、100000。而公式中的低阶、常量、系数三部分并不左右增长趋势,所以可以忽略。如果用大 O 表示法表示刚讲的那两段代码的时间复杂度,就可以记为:T(n) = O(n); T(n) = O(2n2+2n+3)。

时间复杂度分析

  1. 只关注循环执行次数最多的一段代码

    即我们在分析一个算法、一段代码的时间复杂度的时候,只关注循还次数最多的那一段就行。

int leijia(int n)
{
	int sum=0;
	int i=1;
	for(;i<=n;i++)
	{
		sum+=i;
	}
	return sum;
}

还是第一次那段代码,3,4行是常量级别的,与n的大小没有关系,对复杂度也没有影响,循环次数最多的是第5和第7行,这两行代码执行n次,所以这段代码的时间复杂度就是O(n);

  1. 加法法则:总复杂度等于量级最大的那段代码的复杂度
int f(int n)
{
	int sum1=0;
	int sum2=0;
	int sum3=0;
	int i=1;
	int j=1;
	int k=1;
	
	for(;i<=1000;i++)
	{
		sum1+=i;
	}
	
	for(;i<=n;i++)
	{
		sum2+=i;
	}
	for(;j<=n;j++)
	{
		for(;k<=n;k++)
		{
			sum3=sum3+j*k;
		}
	}
	return sum3;
}
	

如上面这段代码,代码可以分3块,分别是求sum1,sum2,sum3。求sum1这段代码运行了100次是个常量,和n,复杂度无关。

再看求sum2这块代码,代码执行n次,所以他的复杂度就是O(n).

最后看看求sum3这块代码,就是O(n).

综合这三段代码的时间复杂度,我们取其中最大的量级。所以,整段代码的时间复杂度就为 O(n2)。也就是说:总的时间复杂度就等于量级最大的那段代码的时间复杂度

3.乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积
还得写一块代码 。。。。。。

int f(int n)
{
	int i=1;
	int sum1=0;
	for(;i<=n;i++)
	{
		sum1=i+ff(i);
	}
	
int ff(int n)
{
	int j=1;
	int sum2=0;
	for(;j<=n;j++)
	{
		sum2+=j;
	}
	return sum2;
}

对于这个代码呢
假设 f() 只是一个普通的操作,那第 5~7 行的时间复杂度就是,T1(n) = O(n)
但是它里面还调用了一个ff函数,它的复杂度是,T2(n) = O(n)。
所以整个f函数的复杂度就是T(n) = T1(n) * T2(n) = O(nn) = O(n2)*。

下面是常见的几种复杂度
分析、统计算法的执行效率和资源消耗_第1张图片ok 就这样先。。

你可能感兴趣的:(分析、统计算法的执行效率和资源消耗)