一、空间复杂度定义
空间复杂度是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度
二、空间复杂度的表示方法
大O渐进表示法
空间复杂度不是计算程序占用了多少字节的空间,因为这种计算没有意义。空间复杂度计算的是程序中变量的个数。
注意:函数运行时多需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时申请的额外空间来确定
简而言之就是,算法函数的传入的参数不算在空间复杂度的计算中
三、实例代码
实例1
冒泡排序算法中的变量有 i、flag、j、tmp,总共4个,是常数个
空间复杂度:O(1)
//冒泡排序(升序) void bubble_sort(int* arr, int size) { int i = 0; int flag = 0; for (i = 0; i < size - 1; i++) { int j = 0; for (j = 0, flag = 0; j < size - 1 - i; j++) { if (arr[j] > arr[j + 1]) { flag = 1; int tmp = 0; tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } if (flag == 0) { break; } } }
实例2
该算法中额外申请了(n+1)个空间
空间复杂度:O(N)
//返回斐波那契数列的前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; }
实例3(递归的空间复杂度)
尽管函数中并没有明显的定义变量,但是每次函数递归时,会创建函数栈帧,调用多少次函数就创建多少层函数栈帧。
空间复杂度:O(N)
long long Fac(long long n) { if (n == 1) return 1; else return n * Fac(n - 1); }
实例4(双目递归的空间复杂度)
该函数递归在递归的时候,先调用Fib(N),再调用Fib(N-1),再调用Fib(N-2),……,再调用Fib(2)
左子树调用完了,函数栈帧销毁,再调用右子树,所以该算法最多只创建N-1层函数栈帧
空间复杂度:O(N)
int fibonacci1(int n) { if (n > 2) return fibonacci1(n - 1) + fibonacci1(n - 2); return 1; }