一.概念
1.函数递归的定义
函数自己调用自己。把一个大型复杂问题转换成一个与原问题相似,但规模较小的子问题来求解,直到子问题不能再拆分,递归就结束了,思想就是大事化小。
2.递归的限制条件
1.存在一个限制条件,当满足这个限制条件时,递归不再继续。
2.每次递归后越来越逼近这个条件。
3.递归的缺点
函数递归可能会造成栈溢出,原因是每次函数调用都会向栈区申请一块空间。这样会大大降低我们程序执行效率。
二.递归题1(n!)
1.求n!
下面命名一个函数fac来求n!,根据上图可得公式:
int fac(int n)
{
if (n == 0) //递归结束的限制条件
return 1;
else
return n * fac(n - 1);
}
int main()
{
int n = 0;
scanf("%d", &n); //输入的 n >= 0
int r = fac(n);
printf("%d的阶乘是:%d", n,r);
return 0;
}
现在,我们来解释一下是如何实现的
假定输入的n为3
想法(便于理解):函数递归就相当于函数的嵌套使用,一个函数里调用另一个函数,因此下图中我把fac函数名更改了,功能还是相同的
蓝色矩形框起来的数字是返回值
三.递归题2(正序输出)
2.输入一个数,要求正序输出它的每一位
如:输入123 输出1 2 3
思路:对这个数依次取余,取整
1234 % 10 == 4
1234 / 10 == 123
123 % 10 == 3
123 / 10 == 12
12 % 10 == 2
12 / 10 == 1
1 % 10 == 1
命名一个函数print(n)
假如输入的n为123
print(12)+3
print(1)+2+3
void print(int n)
{
if (n > 9) //输入的数不是一位数
{
print(n / 10);
}
printf("%d ", n % 10);
}
int main()
{
int n = 0;
scanf("%d", &n);
print(n);
return 0;
}
三.求第n个斐波那契数
1.递归法
斐波那契数:
1 1 2 3 5 8 13 21 …
第一个数和第二个数给定的是1,之后的数等于其前两个数之和
int Fib(int n)
{
if (n <= 2)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int r = Fib(n);
printf("%d\n", r);
return 0;
缺点:当你输入的n很大时,它的运行效率特别特别慢。
2.非递归法
我们不妨把第一个数赋值给变量a,即 int a = 1; 把第二个数赋值给b,即 int b = 1; 现在第三个数就是 c = a+b; 求第三个数时执行了一次,接下来求第四个数,即把图中a,b,c各往后移了一格,因此 a等于上一次的b,b等于上一次的c,即a = b; b = c 以此类推,求第n个数时需要执行n-2次,放入循环