数据结构:时间复杂度和空间复杂度计算

1.什么是时间复杂度和空间复杂度?


1.1算法效率


算法效率分析分为两种:第一种是时间效率,第二种是空间效率。时间效率被称为时间复杂度,
而空间效率被称作空间复杂度。 时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主
要衡量一个算法所需要的额外空间,在计算机发展的早期,计算机的存储容量很小。所以对空间
复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。
所以我们如今已经不需要再特别关注一个算法的空间复杂度。


1.2 时间复杂度的概念


时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运
行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机
器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻
烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比
例,算法中的基本操作的执行次数,为算法的时间复杂度。


1.3 空间复杂度的概念


空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度不是程序占用
了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。空间复杂度计
算规则基本跟实践复杂度类似,也使用大O渐进表示法。
 

 大O的渐进表示法

#include <stdio.h>

// 请计算一下Func1基本操作执行了多少次?
void Func1(int N)
{
	int count = 0;
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < N; ++j)
		{
			++count;
		}
	}
	for (int k = 0; k < 2 * N; ++k)
	{
		++count;
	}
	int M = 10;
	while (M--)
	{
		++count;
	}
	printf("%d\n", count);
}

 Func1 执行的基本操作次数 :F(N)=N^2+N*2+10

        实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法。大O符号(Big O notation):是用于描述函数渐进行为的数学符号。
推导大O阶方法:
        1、用常数1取代运行时间中的所有加法常数。
        2、在修改后的运行次数函数中,只保留最高阶项。
        3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。
使用大O的渐进表示法以后,Func1的时间复杂度为:O(N^2)

 N = 10 F(N) = 100
N = 100 F(N) = 10000
N = 1000 F(N) = 1000000

通过上面我们会发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执
行次数。
另外有些算法的时间复杂度存在最好、平均和最坏情况:
最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)
例如:在一个长度为N数组中搜索一个数据x
最好情况:1次找到
最坏情况:N次找到
平均情况:N/2次找到
在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)
 

 2.时间复杂度与空间复杂度的区别

时间复杂度:

判断算法的时间复杂度通常是通过分析算法中的基本操作次数来进行的。以下是一些常用的判断时间复杂度的方法:

1. 计算操作的执行次数:根据算法的实际代码或伪代码,计算出每个操作(比如循环、条件判断、函数调用等)在最坏情况下执行的次数。

2. 识别循环结构:对于循环结构,需要确定循环的迭代次数,并将循环体中的操作次数乘以迭代次数。

3. 分析递归算法:对于递归算法,可以使用递归树或递归方程的方法来进行分析,推导出递归的深度和每层的操作次数。

4. 考虑最坏情况:时间复杂度通常使用算法最坏情况下的操作次数来表示,这样可以保证算法在任何情况下的时间表现。

5. 忽略常数项和低阶项:在计算时间复杂度时,通常忽略操作次数的常数项和低阶项,只保留最高阶的项,使用大O符号表示。

需要注意的是,时间复杂度只是对算法的一个粗略估计,它描述的是算法运行时间与输入规模的增长趋势,并不具体表示实际的执行时间。此外,时间复杂度是在理论上对算法效率的分析,实际运行时的表现可能受到各种因素影响。

因此,在分析时间复杂度时,需要结合具体的算法实现、输入规模以及实际的运行环境等因素来进行判断和评估。


空间复杂度 

判断算法的空间复杂度通常是通过分析算法在执行过程中所需的额外空间来进行的。以下是一些常用的判断空间复杂度的方法:

1. 计算变量占用的空间:根据算法中定义的变量、数据结构和临时存储空间等,计算出在最坏情况下所需的额外空间。

2. 考虑递归函数调用栈:对于使用递归的算法,需要考虑递归函数调用时占用的栈空间。

3. 分析数据结构的空间复杂度:对于使用的数据结构(如数组、链表、栈、队列等),需要根据其存储方式和元素数量来分析其占用的额外空间。

4. 考虑函数调用和递归深度:在算法执行过程中,如果有函数调用或递归调用,需要考虑每次调用时所需的栈空间。

5. 忽略常数项和低阶项:与时间复杂度类似,空间复杂度的计算中通常忽略常数项和低阶项,只保留最高阶的项,使用大O符号表示。

需要注意的是,空间复杂度表示的是算法在执行过程中所需的额外空间,而不是算法所操作的原始输入数据的空间。因此,在计算空间复杂度时,应将注意力放在算法运行过程中所需额外空间的分析上。

与时间复杂度类似,空间复杂度也只是对算法的一个粗略估计,它描述的是算法所需额外空间随输入规模的增长趋势,并不具体表示实际的空间使用情况。在实际应用中,也要结合具体的算法实现、数据规模以及可用内存等因素来进行判断和评估。


 二者的区别

时间复杂度和空间复杂度是用来衡量算法效率的两个重要指标。它们分别关注算法在执行过程中所需的时间和空间资源消耗。

时间复杂度(Time Complexity)衡量的是算法执行所需的时间,也可以说是算法的运行时间。它描述的是算法执行所消耗的操作步骤数量与输入规模之间的关系。常用大O符号(O)表示时间复杂度。

时间复杂度反映了算法在处理数据时所需的时间随着输入规模的增加而增长的速度。一般来说,时间复杂度越低,算法的执行效率越高。常见的时间复杂度包括常数时间O(1)、线性时间O(n)、对数时间O(log n)、平方时间O(n^2)等。

空间复杂度(Space Complexity)衡量的是算法执行所需的额外空间,也可以说是算法的存储空间。它描述的是算法所需的额外空间与输入规模之间的关系。同样,常用大O符号(O)表示空间复杂度。

空间复杂度反映了算法在处理数据时所需的额外空间随着输入规模的增加而增长的速度。一般来说,空间复杂度越低,算法所需的额外空间越小。常见的空间复杂度包括常数空间O(1)、线性空间O(n)、对数空间O(log n)等。

需要注意的是,时间复杂度和空间复杂度是独立且不可兼得的。某个算法可能在时间复杂度上表现良好,但在空间复杂度上较高,或者反之。因此,在选择算法时,需要根据实际情况综合考虑时间和空间的权衡。

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值