递归是一项很巧妙的技术,它的思想是将一个大问题,拆分成一个个性质相同的细小问题的解题思路与方法。
在C语言中,我们利用函数自己调用自己来实现递归。(包括直接调用与间接调用)。
我们通过做一个小题目,来领略一下递归的巧妙之处。
题目:
小乐乐上课需要走n阶台阶。
因为他腿比较长,所以每次可以选择走一阶或者走两阶。
求他一共有多少种走法?
递归思想解题:
”n阶台阶,共有多少种不同的走法“——这是一个大问题,接下来,我们进行拆分:
我们不知道n阶台阶的走法,
但我们知道1个台阶与2个台阶有多少种走法:
- 1个台阶只有1种走法,一次走完。
- 2个台阶有2种走法,可以一次走完,也可以分两步走完。
所以我们将n阶台阶不断地进行切割拆分,最终切割成很多个1个台阶或2个台阶的组合。
我们可以画出这样一张图(以7个台阶为例):
它们先呈指数式地爆炸,一步步分散下去。
直到只有1个或2个台阶时,再一层一层地返回。返回时带回一个值——根据我们上面的分析,1个台阶的带回来1(只有1种走法),2个台阶的带回来2(有2种走法)。如下图:
最终顶部的数字,就是我们的结果。
思想说完了,现在我们要在C语言中实现。在C语言中 做事,就要遵循它的规则:
- 递归一定要有条件终止
- 递归每次自我调用时,一定要不断地逼近自己地终止条件
这2条很容易去理解:我们可以看出来,递归很像是一种特殊的循环,而上面2条限制其实也就是避免递归陷入死递归中,无法跳出。
代码实现:
#include <stdio.h>
int Sum(int n)
{
//剩1个台阶 -- 返回1
//剩2个台阶 -- 返回2
if(n <= 2)
{
return n;
}
//一分为二地分叉下去
//直到符合上面 n <= 2的条件时,开始返回数据
//然后将分叉地2个数据相加成1个数据,再次返回,直至登顶
//
//计算Sum(n - 2) + Sum(n - 1)时,为递
//计算完毕,return返回数据时,为归
return Sum(n - 2) + Sum(n - 1);
}
int main()
{
int input = 0;
int sum = 0;
scanf("%d", &input);
sum = Sum(input);
printf("%d\n", sum);
return 0;
}