C语⾔:递归解决年龄问题(精细版)
问题:
有5个⼈坐在⼀起,问第5个⼈多少岁,他说⽐第4个⼈⼤2岁。问第4个⼈多少岁,他说⽐第3个⼈⼤2岁。问第3⼈多少岁,他说⽐第2个⼈⼤2岁。问第2个⼈多少岁,他说⽐第1个⼈⼤2岁。最后问第1个⼈,他说他是10岁。编写程序,当输⼊第⼏个⼈时求出其对应的年龄。
分析:
该问题是⼀个递归问题。要求第5个⼈的年龄,必须先知道第4个⼈的年龄,显然第4个⼈的年龄也是未知的,但可以由第3个⼈的年龄推算出来。⽽想知道第3个⼈的年龄⼜必须先知道第2个⼈的年龄,第2个⼈的年龄则取决于第1个⼈的年龄。
⼜已知每个⼈的年龄都⽐其前⼀个⼈的年龄⼤2,因此根据题意,可得到如下⼏个表达式:
age(5)=age(4)+2
age(4)=age(3)+2
age(3)=age(2)+2
age(2)=age(1)+2
age(1)=10
归纳上⾯5个表达式,⽤数学公式表达出来为:
求解第n个⼈的年龄分成两个阶段。第⼀个阶段是“回推”过程,第⼆个阶段是“递推”过程。
在“回推”过程中,利⽤的是n>1时的公式age(n-l)+2。要求的是第n个⼈的年龄,因此⾸先将第n个⼈的年龄回推到第n-1个⼈的年龄,但第n-1个⼈的年龄仍然未知,因此需要继续回推到第n-2个⼈的年龄,第n-2个⼈的年龄仍然未知,需要继续向前回推,如此下去,⼀直回推到第1个⼈的年龄。⽽第1个⼈的年龄是已知的,因此,第⼀阶段的 “回推”结束。
在“递推”过程中,从第1个⼈的年龄可以推出第2个⼈的年龄,从第2个⼈的年龄可以推出第3个⼈的年龄,如此下去⼀直递推到第5个⼈的年龄。
算法设计:
理解了问题分析中的递归处理过程后,算法设计就⾮常简单了。只需要将公式转换成⼀个函数,然后⽤main()函数调⽤它就可以了。
下⾯是完整的代码:
1. #include<stdio.h>
2. int age(int n)
3. {
4. int x;
5. if(n == 1)
6. x=10;
7. else
8. x=age(n-1)+2;
9. return x;
10. }
11. int main()
12. {
13. int n;
14. printf("请输⼊n值:");
15. scanf("%d", &n);
16. printf("第%d个⼈的年龄为%d\n", n, age(n));
17. return 0;
18. }
运⾏结果:
请输⼊n值:5
第5个⼈的年龄为18
知识点补充
由该题的分析过程可知,递归的问题都可以分为“回推”和“递推”两个阶段。⽽且必须存在⼀个能够结束递归过程的条件,如本题中
c语言编写递归函数的age(l)=10,否则递归过程会⽆限制地进⾏下去⽽⽆法结束。
以下对递归法的总结:
递归是设计和描述算法的⼀种强有⼒的⼯具。能够⾤⽤递归来描述的算法通常具有如下的特征:为求解规模为n的问题,⾸先要将它分解成规模较⼩的问题,然后通过这些⼩问题的解,能够⽅便地构造出⼤问题的解。
同时,这些规模较⼩的问题也能够采取同样的分解⽅法分解成规模更⼩的问题,并能够通过这些更⼩的问题的解构造出规模较⼤的问题的解。特别地,当问题规模n=0或n=1时,能直接获得问题的解。
递归算法的执⾏过程分为“回推”和“递推”两个阶段:
1. 在回推阶段,是把较复杂的问题(规模为n)的求解递推到⽐原问题简单⼀些的问题(规模⼩于n)的求解。例如本例中,要求解
age(n),先把它递推到求解age(n-l),⽽要计算age(n-1),⼜必须先计算age(n-2),依次类推,直到计算age(1)为⽌。需要注意的是,在递推阶段,必须要有能够终⽌递归的条件。如本例中n为1时,递推可终⽌。
2. 在递推阶段,当获得最简单情况的解时,如本题中得到age(1)的值,逐级返回,依次得到较复杂问题的解,最终获得所求问题的解。注意:
在编写递归函数时需要注意,函数中定义的局部变量和形式参数只在当前的调⽤层有效,当回推到简单问题时,原来调⽤层中的局部变量和参数都被隐藏起来。每⼀个简单问题层中都有⾃⼰的局部变量和参数。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论