【数据结构】时间复杂度和空间复杂度解析

数据结构前言:

1. 什么是数据结构

打个比方来说不同的数据就相当于不同的书籍,我们经常在图书馆可以看到不同类别的书籍会被整理放在书架上方便查看存放,数据结构就是一种计算机存储管理数据的方式。

2. 什么是算法

算法就是一系列的计算步骤,将我们输入的需要计算的数据转化成输出的结果

算法的时间复杂度和空间复杂度:

1. 为什么要计算算法的时间复杂度和空间复杂度

时间复杂度和空间复杂度可以反应一个算法的好坏,好的算法执行能力强,快;差的算法执行能力弱,慢。比如我们打开一个应用的界面,你一打开就进入了首页,还有种情况你打开等了半天还是在封面广告界面,我相信大多数用户都喜欢前者,算法也是如此,好算法计算机1ms就执行出结果,坏的算法往往执行半天,程序一直在跑,甚至于可能失败。

所以我们需要一些理论来衡量算法的优劣,时间复杂度和空间复杂度由此诞生。选择好的算法,往往在思考算法的过程中也可以锻炼我们的思维能力。

时间复杂度:

时间复杂度表面看起来好像跟时间有关,但其实不是计算算法跑了多少时间的,因为我们知道不同的电脑计算能力,跑程序有强弱之分,一个好的算法在老古董电脑上跑也需要很长的时间,所以为了防止这样的情况误差发生,我们的时间复杂度计算的是一个算法执行了多少次命令操作!

cpp 复制代码
如:

int main()
{
	int a =0;
	printf("%d", a);
	return 0;
}

从进入主函数内部我们总共执行了3次指令,我们称这样的时间复杂度为 O(1); -> 后面会解释为啥不是 O(3)

为了方便我们判断,我们只选取最大的执行项数,N^2, 以阶级区分,为什么怎么做呢?,首先我们先了解有多少种时间复杂度:

因为目前计算机的计算速度基本上都是以亿为单位的,当计算的数量上去之后,一些细枝末节就不予考虑了

拿 F(N) = N^2 + 2*N + 10 举例

当N=10时, F(N) =100+30
当N=100时, F(N) =10000+210
当N=1000时, F(N) =1000000+2010

我们称这种取舍的表示符号O() 为****大O的渐进表示法

时间复杂度计算的是最坏的情况,这样可以保证我们的效率最坏也就是那样,知道预期的结果。

cpp 复制代码
// 大家可以根据以下代码测试cpu性能
// 计算出自己计算机的计算能力

int main()
{
	long long int x = 0;

	int begin1 = clock();
	int n = 10000;
	for (int i = 0; i < n; ++i)
	{
		for (int i = 0; i < n; ++i)
		{
			++x;
		}
	}
	int end1 = clock();

	printf("%lld\n", x);
	printf("%d\n", end1 - begin1);
	return 0;
}

下面我们来个题目分析:

题目一:

题目二:

答案:O(N) -> 2*N+10

题目三:

cpp 复制代码
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);
}

答案:O(N^2) -> N^2+2*N+10

题目四:

cpp 复制代码
// 计算Func3的时间复杂度?
void Func3(int N, int M)
{
	int count = 0;
	for (int k = 0; k < M; ++k)
	{
		++count;
	}
	for (int k = 0; k < N; ++k)
	{
		++count;
	}
	printf("%d\n", count);
}

答案:O(M+N)

题目五:

cpp 复制代码
// 计算Func4的时间复杂度?
void Func4(int N)
{
	int count = 0;
	for (int k = 0; k < 100; ++k)
	{
		++count;
	}
	printf("%d\n", count);
}

答案: O(1) ->100

题目六:

cpp 复制代码
// 计算BubbleSort的时间复杂度?
void BubbleSort(int* a, int n)
{
	assert(a);
	for (size_t end = n; end > 0; --end)
	{
		int exchange = 0;
		for (size_t i = 1; i < end; ++i)
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
				exchange = 1;
			}
		}
		if (exchange == 0)
			break;
	}
}

答案:O(N^2) -> N*(N+1)/2

空间复杂度:

同理空间复杂度也不是去真的算空间的大小,而是计算创建了的变量个数。其他方面同理于时间复杂度。

题目一:

cpp 复制代码
// 计算BubbleSort的空间复杂度?
void BubbleSort(int* a, int n)
{
	assert(a);
	for (size_t end = n; end > 0; --end)
	{
		int exchange = 0;
		for (size_t i = 1; i < end; ++i)
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
				exchange = 1;
			}
		}
		if (exchange == 0)
			break;
	}
}

答案:题目一使用了常数个额外空间,所以空间复杂度为 O(1)

题目二:

cpp 复制代码
// 计算Fibonacci的空间复杂度?
// 返回斐波那契数列的前n项
long long* Fibonacci(size_t n)
{
	if (n == 0)
		return NULL;
	long long* fibArray = (long long*)malloc((n + 1) * sizeof(long long));
	fibArray[0] = 0;
	fibArray[1] = 1;
	for (int i = 2; i <= n; ++i)
	{
		fibArray[i] = fibArray[i - 1] + fibArray[i - 2];
	}
	return fibArray;
}

答案:题目二动态开辟了N个空间,空间复杂度为 O(N)

题目三:

cpp 复制代码
// 计算阶乘递归Fac的空间复杂度?
long long Fac(size_t N)
{
	if (N == 0)
		return 1;
	return Fac(N - 1) * N;
}

答案:题目三递归调用了N次,开辟了N个栈帧,每个栈帧使用了常数个空间。空间复杂度为O(N)

其他关于数据结构的题目分析:

以下的图片内容我小编平时写一些算法题目的思考,大家可以选取看取:

相关推荐
_GR1 小时前
每日OJ题_牛客_牛牛冲钻五_模拟_C++_Java
java·数据结构·c++·算法·动态规划
无限大.1 小时前
c语言实例
c语言·数据结构·算法
@haihi1 小时前
冒泡排序,插入排序,快速排序,选择排序
数据结构·算法·排序算法
丢掉幻想准备斗争2 小时前
数据结构(栈和队列的实现)
数据结构
zengy52 小时前
Effective C++中文版学习记录(三)
数据结构·c++·学习·stl
&梧桐树夏6 小时前
【算法系列-链表】删除链表的倒数第N个结点
数据结构·算法·链表
QuantumStack6 小时前
【C++ 真题】B2037 奇偶数判断
数据结构·c++·算法
wclass-zhengge7 小时前
数据结构篇(绪论)
java·数据结构·算法
Dylanioucn7 小时前
【分布式微服务云原生】探索Redis:数据结构的艺术与科学
数据结构·redis·分布式·缓存·中间件
何事驚慌7 小时前
2024/10/5 数据结构打卡
java·数据结构·算法