1.递归是什么
2.递归的限制条件
3.递归的实战演练
4.递归与迭代
1.递归是什么:
在我们学习C语言中,有时候遇到复杂的问题时候我们需要用到递归的方法。
在C语言中,递归本质就是函数自己调用自己。
下面写一个最简单的递归代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
printf("haha\n");
main();
return 0;
}
代码结果展示:
在这里我们会发现结果一直重复“haha”,产生死循环,并且代码还弹出警告,代码弹出了
stack overflow说明我们内存中的栈溢出了。
1.2递归的思想:
我们通常什么时候去用递归呢?在我们遇到一个处理起来比较大并繁琐的时候,可以去用较小的代码去处理它,这时候我们就可以用到递归方法。
其本质来说就是把大事换成小事来解决它。
我们也可以这样来理解递归:递归中的递看成递推,归看成回归。
后续有代码方便大家更好理解意思。
2.递归的限制条件:
递归有两个必要的限制条件:
1.递归存在限制条件,当满足这个限制条件的时候,递归便不再继续。
2.每次递归调用之后越来越接近这个限制条件。
这两个条件可以使得递归后的减少栈溢出,避免死循环。
3.递归的实战举例:
例1:求取n的阶乘:
//求取n的阶乘
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int Fac(int n)
{
if (n == 0)
return 1;
else
return n * Fac(n - 1);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fac(n);
printf("%d\n", ret);
return 0;
}
n的阶乘公式为:n=n*(n-1)!
它具体是怎么运行的呢?
由图篇可以看出来,当n取3的时候返回值为3*Fac(2),那剩下来的Fac(2)又会跳到Fac函数中运行逐层递进,知道n==0,返回1;这就是我们刚刚提到对推过程中的递推。
然后当n==0;取1时,它就会回归到f(0)1;然后逐步回到3f(2);
这就是对归过程中的回归过程。
以下图更好理解递推与回归的过程:
例2:顺序打印⼀个整数的每⼀位
输⼊⼀个整数m,按照顺序打印整数的每⼀位。
⽐如:
输⼊:1234 输出:1234
输⼊:520 输出:520
代码展示如下:
int print(int n)
{
if (n > 9)
print(n / 10);
printf("%d ", n % 10);
}
int main()
{
int n = 0;
scanf("%d", &n); //scanf不可加\n
print(n);
return 0;
}
结果展示如下:
这里有一点需要注意:在print函数中if条件后没有给else 而是空格后直接使用了printf函数,这时候它会在第一阶段打印函数吗?
其实是不会的,因为递归函数中前面的事情没处理完,它就不会处理后面的,
当Fac函数中的数没有处理完,它自然不会进行打印。
以下图更有助于大家理解。
4.递归与迭代:
迭代就是把一些事情重复去做
循环就是一种迭代
递归与迭代是两种不同对题目的解决方法,他们各自有优点也有缺点:
举个实例:
写一个斐波那契数列:
int Fib(int n)
{
if (n < 3)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
int main()
{
//int count = 0;
int n = 0;
scanf("%d", &n);
int r = Fib(n);
printf("%d", r);
return 0;
}
迭代表现形式:
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n>=3)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int n = 0;
scanf("%d", &n);
int r = Fib(n);
printf("%d\n", r);
return 0;
}
迭代思想:
在这里迭代可以算出运行效率更快,但迭代思路有点难想到,所以大家以后在考虑解决问题这两种思路应该具体情况具体分析。
小结:
本节介绍了函数的递归的一些基本知识,下一节将会带大家用递归思想实践做两个题目,并给大家讲解函数栈帧的创建和销毁让大家深入了解一下函数的运行。
大家觉得有用的话可以给主播点点赞和关注,你们的支持就是我最大的动力❤