算法效率的度量
目录空间复杂度
问题规模n与内存开销的关系,空间复杂度用 S(n) 表示,S 即 space,其值使用大O表示法:O(n)
空间复杂度与算法所需的数据量有关,而与算法结构(顺序、分支和循环)无关,因为算法代码总是占用一块固定大小的内存,而数据是动态变化的,需要足够的内存来存放。
空间复杂度的计算
例1 与问题规模无关
void print_star(int n){
int i=0;
while(i<n){
printf("* ");
}
}
对于与问题规模无关的算法:S(n) = O(1)
例2 与问题规模有关
void demo(int n){
int a[n];
int i;
}
- 变量 a 所占内存与问题规模 n 有关,假设整个函数占用内存大小为 C,int 类型为 4 B。则该算法的空间复杂度 S(n) = 4n+4+C。
- 当 n -> ∞, (4n+4+C)/n=4,S(n) 与 n 的同阶,故该算法空间复杂度为 S(n) = O(n)。
void demo(int n){
int a[n][n];
int i;
}
- S(n) = O(n2)
void demo(int n){
int a[n][n];
int b[n];
}
- S(n) = O(n2) + O(n) = O(n2)
例3 递归算法
// n 与数据量无关
void print_star(int n){
int i;
if (n>1){
print_star(n-1);
}
printf("* ");
}
// n 与数据量有关
void print_star2(int n){
int i[n];
if (n>1){
print_star(n-1);
}
printf("* ");
}
- 递归算法,调用自身时并不会再复制一份函数代码,只是创建执行函数代码所需的所有变量。随着递归层数的增加,算法创建的变量越多,内存开销越大。
设函数代码占用内存大小为 C, int 为 4 字节.
-
当 问题规模 n 不影响数据量,S(n) = C + 8n, 算法的空间复杂度S(n) = O(n)
-
当 问题规模 n 与数据量有关, S(n) = C + 4n + (1+2+3+…+n)=n(1+n)/2 +4n+C = n2/2 + 9n/2 + C, 算法的空间复杂度 S(n) = O(n2)。
常见空间复杂度
由小到大排列:
O(1) < O(log2n)< O(n) < O(nlog2n)< O(n2) < O(n3) < O(2n) < O(n!) < O(nn)