文章目录
- 【数据结构篇】算法征途:穿越时间复杂度与空间复杂度的迷雾森林
-
- [一、 什么是算法](#一、 什么是算法)
-
-
- [1. 算法的定义](#1. 算法的定义)
-
- [1.1 算法的五个特征](#1.1 算法的五个特征)
- [1.2 好算法的特质](#1.2 好算法的特质)
- [2. 时间复杂度](#2. 时间复杂度)
- [3. 空间复杂度](#3. 空间复杂度)
-
【数据结构篇】算法征途:穿越时间复杂度与空间复杂度的迷雾森林
💬欢迎交流:在学习过程中如果你有任何疑问或想法,欢迎在评论区留言,我们可以共同探讨学习的内容。你的支持是我持续创作的动力!
👍点赞、收藏与推荐:如果你觉得这篇文章对你有所帮助,请不要忘记点赞、收藏,并分享给更多的小伙伴!你们的鼓励是我不断进步的源泉!
🚀推广给更多人:如果你认为这篇文章对你有帮助,欢迎分享给更多对机器学习感兴趣的朋友,让我们一起进步,共同提升!
一、 什么是算法
程序 = 数据结构 + 算法
1. 算法的定义
算法是对特定问题求解步骤的一种描述,它是指令的有限序列,其中的每条指令表示一个或多个操作。
此外,算法还有五个重要的特征
1. 有穷性
2. 确定性
3. 可行性
4. 输入
5. 输出
接下来我们分别来看这五个特性
1.1 算法的五个特征
1. 有穷性
一个算法必须在有穷步之后结束,且每一步都可在有穷时间内完成。
这里需要注意的是 算法必须是有穷的,而程序可以是无穷的。
2. 确定性
算法中每条指令必须有确切的含义,对于相同的输入只能得出相同的输出。
3. 可行性
算法中描述的操作都可以通过已经实现的基本运算执行有限次来实现。
4. 输入
一个算法有零个或多个输入,这些输入取自于某个特定的对象的集合
5. 输出
一个算法有一个或多个输入,这些输出是与输入有着某种特定关系的量
1.2 好算法的特质
1. 正确性
算法应该可以正确地解决求解的问题
2. 可读性
算法应具有良好的可读性,以帮助人们可以理解
3. 健壮性
输入非法数据时,算法能适当地做出反应或进行处理,而不会产生莫名奇妙的输出结果
4. 高效率与低存储量要求
高效率 代表花费的时间少 时间复杂度低
低存储量需求是不费内存 空间复杂度低
- 总结:
2. 时间复杂度
可以事先预估时间开销T(n) 与问题规模n 的关系 (T 表示"time")
这里我们用一串代码来看下
c
#include <stdio.h>
// 递增形love you!
void loveyou(int n){ // n 为问题规模
int i = 1;
while(i <= n){
printf("love you %d\n", i);
i++;
}
printf("I love you too!\n");
}
int main(){
loveyou(500);
return 0;
}
上述代码结果:
这里我们问题规模是 500 所以我们的:是T(500) = 1 + 501 + 2*500 + 1
如果把500换成n的话 那么
表达式:T(n) = 3n + 3
但是如果表达式多了怎么办呢 那么
T1(n) = 3n + 3
T2(n) = n2+3n + 1000
T3(n) = n3+ n2 + 9999999
若 n = 3000 ,则 :
3n = 9000 比 T1(n) = 3n + 3 =9003
n2=9,000,000 比T2(n) = n2+3n + 1000 = 9,010,000
n3=27,000,000,000 比 T3(n) = n3+ n2 + 9999999 = 27,018,999,999
这时我们可以发现 我们可以只考虑阶数高的部分 可以简化下:
T1(n) = O(n)
T2(n) = O(n2)
T3(n) = O(n3)

算法的复杂度:
最坏时间复杂度: 最坏情况下算法的时间复杂度
平均时间复杂度:所有输入示例等概率出现的情况下,算法的期望运行时间
- 总结
3. 空间复杂度
c
#include <stdio.h>
// 递增形love you!
void loveyou(int n){ // n 为问题规模
int i = 1;
while(i <= n){
printf("love you %d\n", i);
i++;
}
printf("I love you too!\n");
}
int main(){
loveyou(500);
return 0;
}
解释: 当我们编辑好这段代码是 其实需要占多少空间 是已经固定的 这片空间的大小 其实是跟我们问题规模没有关系的
我们在调用这段代码时 其实会传入一个int型的参数
然后我们还定义了一个int型的变量i(int i = 1)
这里需要注意的是 int n (这里的n指的是问题规模)但是不管n的值怎么变化 这个算法执行中 都是一个固定不变的常数值。
无论问题规模怎么变,算法运行所需的内存空间都是固定的常量。
所以这里的算法的空间复杂度 为
常数阶:S(n) = O(1)
- 注 S表示的是"Space"
并且还需要注意的是 如果是常数阶的话 那么我们就可以称这种算法可以原地工作
我们来看一段简单的示例代码:
c
void test(int n){
int flag[0];//声明长度为n的数组
int i;
//.....此处省略很多代码

我们经过上一个例子可以看出 和问题规模是没有关系的 那么这里我们假设int型变量占的是4个字节(4B)
则所需内存空间 = 4+ 4n + 4 = 4n + 8
那我们就可以写成 S(n) = O(4n + 8) 他的阶数为n 那么
空间复杂度其实是 S(n) = O(n)
我们其实可以看出 如果在函数当中我们定义了某种变量,但是这个变量所占的空间和问题规模n没有关系的话 这个类型的变量 最多也就是在我们的表达式当中 给我们增添一个常数项 但我们最终要转换成大O表示法 也就是关心阶数的 所以这种常数项 对我们最终结果不会产生任何结果
因此:我们只需要关注存储空间的大小与问题规模相关的变量就可以了

你好,我是意疏。我们一起进步。

意气风发,漫卷疏狂
学习是成长的阶梯,每一次`的积累都将成为未来的助力。我希望通过持续的学习,不断汲取新知识,来改变自己的命运,并将成长的过程记录在我的博客中。如果我的博客能给您带来启发,如果您喜欢我的博客内容,请不吝点赞、评论和收藏,也欢迎您关注我的博客。
您的支持是我前行的动力。听说点赞会增加自己的运气,希望您每一天都能充满活力!
愿您每一天都快乐,也欢迎您常来我的博客。我叫意疏,希望我们一起成长,共同进步。
我是意疏 下次见!