03.数据结构基础—算法的时间复杂度
一.空间复杂度
定义:除算法输入和输出数据所占用的空间外,算法临时开辟的储存空间。
二.非递归算法的空间开销
#include <iostream>
using namespace std;
void test(int n){
int i = 1;
while(i<=n){
i++;
cout<<"测试 "<<i;
}
cout<<"总测试 "<<n;
}
int main()
{
test(100);
return 0;
}
这段代码在内存中,本身会占用一定空间
其次,变量i和n也会占用空间
所以总占用空间就是代码本身+变量等
(本质上还有其他信息,这里举变量为例子)
在这里n如论如何变幻,内存空间都是不变的,所以空间复杂度为:S(n) = O(1)
算法所需内存空间为常量——算法原地工作
void test(int n){
int flag[n];
int i;
//剩余代码省略
}
这段代码中相对于前面多了一个数组,但是变化是很大的。
当我们的n变化时,我们互会发现,空间的开辟和n是有变化的
n增大一个,空间就会多出一块。所以空间复杂度为:S(n)= O(n)
只需关注数组的n即可。也就是只需要关注与问题规模n相关的变量。
void test(int n){
int flag[n][n];
int i;
//剩余代码省略
}
这次将数组改为二维数组,此时空间复杂度为:S(n) = O(n²)
void test(int n){
int flag[n][n];
int other[n];
int i;
//剩余代码省略
}
此时S(n)= O(n²+O(n)+O(1)。
此时用加法规则,取最高项并去掉系数。
则S(n)= O(n²)
三.递归算法的空间开销
#include <iostream>
using namespace std;
void test(int n){
if(n>1){
test(n-1);
}
cout<<n<<endl;
}
int main()
{
test(4);
return 0;
}
输出值为1,2,3,4
我们分析一下:
假设运行一次空间是k,我们调用了4次,所以应该是4k
同理n次时,时nk,所以S(n)=O(n)
空间复杂度=递归调用的深度(非所有)
当我们在上面的例子中加入一个数组时:
#include <iostream>
using namespace std;
void test(int n){
int flag[n];
if(n>1){
test(n-1);
}
cout<<n<<endl;
}
int main()
{
test(4);
return 0;
}
此时会发现每次调用时,因为n的不同,导致数组需要的空间不同
1+2+3+……+n=[n(1+n)]/2 = ½n²+½n
所以S(n)=O(n²)