递归调用是嵌套调用的一种特殊情况。在调用一个函数的过程中,又直接或间接的调用该函数本身,称为函数的递归调用。递归调用可以分为两种:一种是直接递归调用,另一种是间接递归调用。
例如:
“→f()→f()”为直接递归调用,“→f1()→f2()→f1()”为间接递归调用。
如下所示,在调用f()函数的过程中,又需调用f()函数,这是直接调用函数本身,是直接递归调用。而图6.6中,在调用f1()函数时要调用f2()函数,而调用f2()函数过程中又需调用f1()函数,这是间接调用函数本身,是间接递归调用。
从直接递归调用和间接递归调用过程可以看出,递归函数在无休止的直接或间接调用自身,而这种无休止在程序中是不能出现的,因此必须在函数内加上终止递归调用的条件,当条件满足时就结束递归调用,逐层返回。
图6.6 函数和递归调用
递归调用过程(两个阶段):
(1)递推阶段:将原问题不断地分解为新的子问题,逐渐从未知向已知的方向推测,最终达到已知的条件(即递归结束条件),这时递推阶段结束。
(2)回归阶段:从已知条件出发,按照“递推”的逆过程,逐一求值回归,最终到达“递推”的开始处,结束回归阶段,完成递归调用。
【例6.10】用递归法求n!。
为了方便理解题目,我们首先进行一下题目分析:
n!=n*(n-1)*(n-2)*……*2*1=n*(n-1)!
例如:
5!=5*4*3*2*1=5*4!
将求阶乘的函数定义为fun(),则5!=fun(5)=5*4*3*2*1=5*4!,而4!也可以表示成4!=fun(4)=4*3*2*1=4*3!,因此5!=5*fun(5-1)!。
下面以用函数fun()求5!的过程,如图6.7所示:
如果求n!,只需将5换成n即可,即fun(n)=n*fun(n-1),但是还要注意一个隐含条件,就是0和1的阶乘都是1,而用函数fun()来求阶乘fun(0)、fun(1)很明显是错误的。因此,要把当n等于0和1的时候分出来求。
用数学公式表述如下:
用递归公式表示如下:
图6.7 递归法求5!
程序内容如下:
1 #include<stdio.h>
2 int fun(int n) //定义求阶乘的递归函数
3 {
4 int s; //定义s为返回函数值的变量(www.xing528.com)
5 if(n==0||n==1)
6 s=1;
7 else
8 s=n*fun(n-1); //调用函数本身
9 return s; //返回函数值
10 }
11 int main()
12 {
13 int n;
14 printf("n=");
15 scanf("%d",&n);
16 printf("%d!=%d\n",n,fun(n));
17 return 0;
18 }
程序结果如图6.8所示:
图6.8 例6.10程序结果图
【例题中关键问题说明】
请注意每次调用fun()函数后其返回值返回的位置。例如:当n=6时,调用函数s=6*fun(5)中,而fun(5)=5*fun(4),fun(4)=4*fun(3),fun(3)=3*fun(2),fun(2)=2*fun(1)。因为fun(1)=1,则fun(2)=2*1,fun(3)=3*2,fun(4)=4*6,fun(5)=5*24,fun(6)=6*120,即为720。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。