1.理解递归在程序里如何运行
(1)示例
#include<stdio.h>
void f(int n){
printf("Level %d : n location %p",n, &n); /* 1 */
if(n < 4){
f(n+1); /*3*/
}
printf("Level %d : n location %p",n, &n); /* 2 */
}
int main(){
f(1);
return 0;
}
结果:
Level 1 : n location 62fe30
Level 2 : n location 62fe00
Level 3 : n location 62fdd0
Level 4 : n location 62fda0
Level 4 : n location 62fda0
Level 3 : n location 62fdd0
Level 2 : n location 62fe00
Level 1 : n location 62fe30
1.解释:
1.以递归那行语句,即/3/为分界,第3句前面为前半部分,后面为后半部分
2.前半部分:Level n=1、2、3、4,被调用函数的顺序是从1往4递增的,输出/1/语句是顺序出
3.后半部分:(多读几遍就可以理解的),Level n=4、3、2、1,被调用函数的顺序是从4往1递减的,输出/2/语句是逆序出的
4总结:
递归语句前的语句,和各级本调用函数具有相同的执行顺序;
递归语句之后的语句,和各级被调用函数有相反的执行顺序
先(递归语句前的)进后(递归语句后的)出,后进先出
2解释:
递归根本:当某一级递归结束,则该级函数马上将程序的控制权交给该函数的调用函数
详细解释:main()函数调用f()函数称为“第一级递归”,然后f()函数调用其本身称为“第二级递归”。第二级递归调用第三极递归,以此类推。以上程序共有四级递归。
比如说第四级调用,输出了语句#1之后,判断n < 4时是不成立的,所以不再继续递归调用,而是输出语句#2,输完语句#2之后,第四级调用就结束了,此时它就会将控制权交给第三级调用,第三级调用函数中前一个执行过的语句是在if语句中进行第四级调用,因此,当第三级调用获得第四级给它的控制权时,它继续执行后面的代码,即执行打印语句#2,这就输出了第6句话。当第三级调用结束后,第二级调用函数开始继续执行,即输出了第7句话。以此类推。
通过输出语句中n的地址,得出结论:每一级的递归都是它自己的私有变量n,关键在于调用Level1地址和返回时的Level1地址是相同的。
递归的基本原理(感谢😉)
2.递归是什么
递归算法是一种直接或间接调用自身函数或者方法的算法
通俗说,递归的算法实质是把问题分解成规模缩小的同类问题的子问题,使问题更以解决,然后递归调用。
3.递归的基本原理
1.每一级的函数调用都有自己的变量
2.每一次函数调用都会有一次返回,并且是某一级递归返回到调用它的那一级,而不是返回到main()函数种种那个的初始调用部分
3.递归函数中,位于递归调用前的语句和各级被调用函数具有相同的执行顺序。
4.递归函数中,位于递归调用后的语句的执行顺序和各个被调用函数的顺序相反。
5.虽然每一级递归都有自己的变量,但是函数代码并不会得到复制。
6.递归函数中,必须包含终止递归的语句
4.写递归的一般步骤
1.确定递归公式及递归边界(状态转移方程)
2.写代码时先写边界条件,再写递归语句
5.递归的优化方法
(1)考虑是否重复计算
使用递归的时候不进行优化,是有非常非常非常多的子问题被重复计算的。因此,使用递归的时候,必要须要考虑有没有重复计算,如果重复计算了,一定要把计算过的状态保存起来。
(2)考虑尾递归
递归通常是从上往下递归,直到递归到最低,在一层一层这把值返回。
不过,有时候当 n 比较大的时候,例如当 n = 10000 时,那么必须要往下递归10000层直到 n <=1 才将结果慢慢返回,如果n太大的话,可能栈空间会不够用。这个时候,就可以用尾递归优化来解决。
顾名思义,尾递归就是从最后开始计算, 每递归一次就算出相应的结果, 也就是说, 函数调用出现在调用者函数的尾部, 因为是尾部, 所以根本没有必要去保存任何局部变量。直接让被调用的函数返回时越过调用者, 返回到调用者的调用者去。
我都能写到这?你都能看到这儿?咱们简直太棒啦!!!
下边还有更为详细精彩的博客内容哦,对应习题也有啊,不累的话就再瞅瞅吧🤩