前面已经介绍了时间空间复杂度的具体计算,这里将结合具体代码来详细分析时间和空间复杂度。
例1
void print(void){
for(i = 0; i < n;i ++)// 执行n次
for(j = 0; j < n;j ++)// 执行n次
printf("hello world\n")// 执行?次
}
时间复杂度:
由于执行次数最多语句为printf("hello world\n"),当i=0执行n次,i=1执行n次,当i=2执行n次,....,因此printf("hello world\n")执行次数为n+n+..+n=n^2,所以复杂度为O(n^2)=O(n^2)
空间复杂度:
只有调用函数才使用栈,所以执行次数为1,所以复杂度为O(1)
例2
void print(void){
for(i = 0; i < n;i ++)// 执行n次
for(j = i; j < n;j ++)// 执行n次
printf("hello world\n")// 执行?次
}
时间复杂度:
执行最多语句为printf("hello world\n"),当i=0执行n次,当i=1执行n-1,当i=2执行n-2次,...,因此执行printf("hello world\n")次数为n+(n-1)+(n-2)+..+1=(n+1)n/2,所以复杂度为O((n+1)n/2)=O(n^2)
空间复杂度:
不存在额外空间分配/使用,所以复杂度O(1)
例3
static int n, *p[n];
void print(void){
for(i = 0; i < n;i ++)// 执行n次
for(j = i; j < n;j ++)// 执行n次
*p[j] = malloc(sizeof(int))// 执行?次
}
时间复杂度:执行最多语句为*p[j] = malloc(sizeof(int)),当i=0执行n次,当i=1执行n-1,当i=2执行n-2次,...因此执行*p[j] = malloc(sizeof(int))次数为n+(n-1)+(n-2)+..+1=(n+1)n/2,所以复杂度为O((n+1)n/2)=O(n^2)
空间复杂度:
分配空间最多语句为*p[j] = malloc(sizeof(int)),当i=0执行n次,当i=1执行n-1,当i=2执行n-2次,...因此执行*p[j] = malloc(sizeof(int))次数为n+(n-1)+(n-2)+..+1=(n+1)n/2,所以复杂度为O((n+1)n/2)=O(n^2)
例4
long f(int n){
if(n == 0) return 1;
else return f(n-1);
}
时间复杂度:
执行最多语句为return f(n-1),求f(n)先求f(n-1)一次,求f(n-1)先求f(n-2)一次,求f(n-2)先求f(n-3)一次,...,因此return f(n-1)执行1+1..+1=n,复杂度O(n)
空间复杂度:
分配空间最多语句为f函数调用,求f(n)先求f(n-1)压栈一次,求f(n-1)先求f(n-2)压栈一次,求f(n-2)先求f(n-3)压栈一次,...,因此f压栈总共1+1...+1=n,复杂度O(n)
例5
int i = 1, n = 100;
while( i < n )
i = i * 2;
时间复杂度:
执行最多语句为while( i < n ) i = i * 2,分析可知执行若干次2相乘然后循环退出,设循环次数为x,那么则有2^x=n,得到x=(log2)n,总共执行次数为(log2)n+(log2)n=2((log2)n),所以复杂度为O(2((log2)n))=O((log2)n)
空间复杂度:
不存在额外使用/分配空间,所以O(1)
例6
int f(int n){
if( n == 1) return 1;
else return n * f(n-1);
}
时间复杂度:
执行最多语句为return n * f(n-1),求f(n)先求f(n-1)一次,求f(n-1)先求f(n-2)一次,求f(n-2)先求f(n-3)一次,...,因此return n * f(n-1)执行1+1..+1=n,复杂度O(n)
空间复杂度:
分配空间最多语句为f函数调用,求f(n)先求f(n-1)压栈一次,求f(n-1)先求f(n-2)压栈一次,求f(n-2)先求f(n-3)压栈一次,...,因此f压栈总共1+1...+1=n,复杂度O(n)
总结:
判断执行最多语句,计算次数之和,最后仅保留最高阶数