探讨算法的空间复杂度:即衡量算法执行时所需开辟的额外空间大小
前次我们讨论了时间复杂度,今回则来探索空间复杂度的奥秘!
空间复杂度是对算法在执行过程中所占据的临时空间的一个度量标准。
与时间复杂度不同,它并不直接计算算法具体占用的内存字节数。
空间复杂度主要计算的是算法执行过程中额外开辟的变量的数量,同样适用大O渐近法。
请注意,函数在编译期间就已经确定了其运行所需的栈空间(如存储参数、局部变量、寄存器信息等)。而空间复杂度则主要关注函数在运行期间显式申请的额外空间。
以冒泡排序算法为例,它并未定义大量的额外变量,仅需三个变量,因此其空间复杂度可视为常数阶O(1)。
在评估空间复杂度时,需注意其与数据规模N的关系。
当算法中需要开辟空间时,需考虑这个空间与N的关系。
与之前的斐波那契数列递归代码不同,此处我们创建了一个新数组来保存计算结果。
该数组malloc了n+1个长整型空间,因此其空间复杂度为O(N)。
关于空间重复使用的问题
那么对于斐波那契数列的递归算法,其空间复杂度又是多少呢?
答案同样是O(N)。
对于递归算法,其开辟的函数栈帧空间是可以重复利用的。
例如在fib(8)的调用过程中,其开辟的函数栈帧在后续的fib函数调用中可以被重复使用。
这里f1和f2虽然是两个函数调用,但它们执行的是相同的功能。它们的函数调用空间实际上是一个共享的,f2继承了f1销毁后的空间。
这就像每次新的递归都相当于开一家新饭店,但如果想再次品尝东北菜,不必再开新店,只需去已有的东北菜馆即可。
斐波那契数的递归算法在数字非常大时会频繁递归,导致栈溢出。
虽然函数本身的空间不计入时间复杂度范畴,但这里讨论的是递归调用时额外开辟的函数栈帧空间。
如果递归调用了N-1次,每个栈帧使用常数个空间,那么其空间复杂度为O(N)。
时间复杂度和空间复杂度都是评估算法性能的重要指标。在未来的面试中,高效的算受到HR的青睐。
多刷题、积累经验、提升能力,写出优秀的算法是指日可待的(不是吗?)。
-
为了助力大家轻松、高效地学习C语言/C++,我特地分享了精心收集的资源。从零基础开始,助你在C语言学习之路上披荆斩棘!
编程学习书籍分享:
编程学习视频分享:
- [视频名称] - [讲师/来源]
除了上述资源外,我还整理分享了源码、项目实战视频、项目笔记以及基础入门教程等资料。
更重要的是,你可以在群里面与其他编程爱好者交流、提问哦!