算法的时间复杂度与空间复杂度(总结合集+例子)

定义

时间复杂度

  在进行算法分析时,语句总的执行次数 T ( n ) T(n) T(n)是关于问题规模 n 的函数,进而分析 T ( n ) T(n) T(n)n 的变化情况并确定 T ( n ) T(n) T(n)的数量级。算法的时间复杂度,也就是算法的时间度量,记作 T ( n ) = O ( f ( n ) ) T(n) = O(f(n)) T(n)=O(f(n))。其中 f ( n ) f(n) f(n)是问题规模 n 的某个函数。

空间复杂度

  通过计算算法所需的储存空间实现,算法空间复杂度的计算公式记作:
S ( n ) = O ( ( f ( n ) ) ) S(n) = O((f(n))) S(n)=O((f(n)))
其中,n 为问题的规模, f ( n ) f(n) f(n)为语句关于 n 所占存储空间的函数。

时间复杂度的计算方法

即推导大O阶方法
1.用常数1取代运行时间中的所有加法常数。
2.在修改后的运行次数函数中,只保留最高阶项。
3.如果最高阶项存在且不是1,则去除与这个项相乘的常数。
得到的结果就是大O阶

  下面给出实例具体看如何求解时间复杂度。

1.常数阶

  例如下面这段代码:

int a = 1, b = 2;    /*执行1次*/
a = a + b;    /*执行1次*/
b = b + a;    /*执行1次*/

每段代码均执行一次,不断执行多少段这样的代码,其次数都是常数,是有限的,所以此时其具有O(1)的时间复杂度,又称为常数阶。

2.线性阶

  循环结构对时间复杂度具有较大的影响

  下面这段代码,时间复杂度为O(n),因为循环体中的代码要执行 n 次。

int i, sum = 0;
for(i = 0; i < n; i++)
{
    
    
	sum = i + j;
}

3.对数阶

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

  上面这段代码,设循环次数为 x x x,则得到下面等式:
2 x = n x = l o g 2 n 2^x = n \\ x = log_2n 2x=nx=log2n
所以这个循环的时间复杂度为O( l o g n logn logn)

4.平方阶

  下面给出一个循环嵌套:

int i,j;
for(i = 0; i < n; i++)
{
    
    
	for(j = 0; j < n; j++)
	{
    
    
		printf("times");
	}
}

循环了 n ⋅ n n \cdot n nn次,所以这段代码的时间复杂度是O( n 2 n^2 n2)。

5.一个例子

int i,j;
for(i = 0, i < n; i++)
{
    
    
	for(j = i; j < n; j++)
	{
    
    
		printf("times");
	}
}
i 内循环执行次数
0 n
1 n - 1
. . . .\\.\\. ... . . . .\\.\\. ...
n - 1 1

所以总的执行次数为:
n + ( n − 1 ) + ( n − 2 ) + . . . + 1 = n ( n + 1 ) 2 = n 2 2 + n 2 n + (n-1) + (n-2) + ... + 1 = \frac{n(n+1)}{2} = \frac{n^2}{2} + \frac{n}{2} n+(n1)+(n2)+...+1=2n(n+1)=2n2+2n
代入开头给出的求解方法

第一步:没有加法常数不予考虑;

第二步:只保留最高阶项,因此保留 n 2 2 \frac{n^2}{2} 2n2

第三步:去除这个项相乘的常数,也就是去除 1 2 \frac{1}{2} 21

最终得到这段代码的时间复杂度为O( n 2 n^2 n2)。

常见的时间复杂度

执行次数函数 非正式术语
12 12 12 O ( 1 ) O(1) O(1) 常数阶
2 n + 3 2n + 3 2n+3 O ( n ) O(n) O(n) 线性阶
3 n 2 + 2 n + 1 3n^2 + 2n + 1 3n2+2n+1 O ( n 2 ) O(n^2) O(n2) 平方阶
5 l o g 2 n + 2 5log_2n + 2 5log2n+2 O ( l o g n ) O(logn) O(logn) 对数阶
2 n + 3 n l o g 2 n + 19 2n + 3nlog_2n+19 2n+3nlog2n+19 O ( n l o g n ) O(nlogn) O(nlogn) n l o g n nlogn nlogn
6 n 3 + 2 n 2 + 3 n + 4 6n^3 + 2n^2 + 3n +4 6n3+2n2+3n+4 O ( n 3 ) O(n^3) O(n3) 立方阶
2 n 2^n 2n O ( 2 n ) O(2^n) O(2n) 指数阶

其时间复杂度所耗费的时间从小到大依次是:

O ( 1 ) < O ( l o g n ) < O ( n ) < O ( n l o g n ) < O ( n 2 ) < O ( n 3 ) < O ( 2 n ) < O ( n ! ) < O ( n n ) O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n) O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)

  用 MATLAB 画了上表中的几个图形,进行比较,也可以得到相同的结论。matlab

算法空间复杂度

  算法的空间复杂度通过计算算法所需的储存空间实现,算法空间复杂度的计算公式记作:
S ( n ) = O ( ( f ( n ) ) ) S(n) = O((f(n))) S(n)=O((f(n)))
其中,n为问题的规模,f(n)为语句关于n所占存储空间的函数。

其实可以这样理解,比如要去在某个范围寻找 n 这个数字,一般的算法是要遍历这个范围,其时间复杂度比较大;但是可以牺牲空间复杂度去换取时间的减少,就是可以事先存储这个范围的数组,对应序列下标,每次去判断当前数是不是与n相等,每次的时间复杂度为O(1),综合起来的次数是有限的,还是O(1),但是空间复杂度却增大了。

− − − − − − − − − − − − − − − − ----------------
该文章首发于 zyairelu.cn
欢迎来到我的网站进行评论及研讨
个人邮箱[email protected]
− − − − − − − − − − − − − − − − ----------------

猜你喜欢

转载自blog.csdn.net/weixin_42731543/article/details/102588643
今日推荐