目录
一 简介
在C语言中,计算10的阶乘(即10!)可以通过循环或者递归两种方式进行实现。
二 代码实现
方法一:使用循环
#include <stdio.h>
int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; ++i) {
result *= i;
}
return result;
}
int main() {
int fact_10 = factorial(10);
printf("10! = %d\n", fact_10);
return 0;
}
方法二:使用递归
#include <stdio.h>
int factorial(int n) {
if (n == 0 || n == 1) { // 阶乘的基本情况
return 1;
} else {
return n * factorial(n - 1); // 递归调用
}
}
int main() {
int fact_10 = factorial(10);
printf("10! = %d\n", fact_10);
return 0;
}
三 时空复杂度
A.循环实现
时间复杂度分析:
factorial()
函数中的循环执行次数与输入参数n
直接相关,对于任意给定的n
,循环会执行n
次。因此,这个函数的时间复杂度是线性的,记作 O(n)。
空间复杂度分析:
在factorial()
函数中,我们只定义了一个变量result
来存储结果,其空间需求不随输入n
的变化而变化,所以空间复杂度为常量级,记作 O(1)。
而在main()
函数中,虽然没有显式创建额外的数据结构,但编译器会在栈上为局部变量fact_10
分配内存,同样其空间需求也是固定的,不会随着问题规模的增长而增长,故main()
函数的空间复杂度也为 O(1)。
综上所述,整个程序的时间复杂度为 O(n),空间复杂度为 O(1)。对于给定的例子factorial(10)
,实际执行了10次乘法操作。
B.递归实现
时间复杂度分析:
对于递归函数factorial(n)
,每次调用自身都会减小问题规模(即n值减1),直到达到基本情况(n为0或1)。由于每个整数n都要经历从n到1的所有递归调用层级,所以总的递归调用次数是n。因此,该函数的时间复杂度为 O(n)。
然而,需要注意的是,尽管递归树的深度与输入n相同,但由于每次递归调用都会执行一次乘法操作,且所有这些操作都是在栈上顺序完成的,故其实际的计算工作量随着n的增大而线性增长,所以时间复杂度依然可以认为是 O(n)。
空间复杂度分析:
递归函数factorial()
使用了系统栈来存储每次递归调用时的状态,包括局部变量和返回地址等信息。最坏情况下,当递归到达最底层时,栈上会保存n层递归调用的信息,每层需要的空间是常量级别的,因此,递归版阶乘函数的空间复杂度为 O(n)。
总的来说,在这个特定的例子中,调用factorial(10)
将进行10次递归调用,产生O(n)的时间复杂度和空间复杂度。