C语言汉诺塔与青蛙跳台阶——递归的简单应用
Posted 张同学吧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言汉诺塔与青蛙跳台阶——递归的简单应用相关的知识,希望对你有一定的参考价值。
什么是递归
程序反复调用自身即是递归(recursion)
它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。 递归的主要思考方式在于:把大化小,把求解的过程分解为一块块相似的套娃。
递归的两个必要条件:
1、存在限制条件,当满足这个限制条件的时候,递归便不再继续。
2、每次递归调用之后越来越接近这个限制条件。
相信很多初学者总是去想扣明白每一次递归都干了什么,这是一个思维误区,很容易就把自己绕进去。那既然递归是一个反复调用自身的过程,这就说明它每一级的功能都是一样的,因此我们只需要关注简单的2~3级递归的解决过程即可。
所以我们应该主要关注:1.我们要的结果递归方程是什么?2.终止条件是什么?3.递归应该实现什么功能?
汉诺塔
我们先看三个盘子怎么移动:
不难发现,我们第一步要做的就是把其他盘子通过c柱移动到b柱,最后把最大盘放到c柱上。这时的a柱是起始位,c柱是中间位,b柱是终点位。最后一步时,因为最大的盘子已经放到了c柱上,所以无论怎样移动最大的盘子位置都不会再发生改变,所以我们就可以忽略掉最大的盘子。现在就变成了两个盘子要从b柱移动到c柱上,这时的b柱是新起始位,a柱是新中间位,c柱是新终点位。
void move(char x, char y) {
printf("%c—>%c ", x, y);//输出移动路线
}
void Hano(int n,char A,char B,char C) {//A为起始位,B为中间位,C为目标位
if (n == 1) {
move(A, C);
}
else {
Hano(n - 1, A, C, B);//位关系更新
move(A, C);
Hrino(n - 1, B, A, C);//位关系更新
}
}
int main() {
int n = 0;
char A = 'a';
char B = 'b';
char C = 'c';
Hano(4, A, B, C);//设定A为起始位,B为中间位,C为目标位
return 0;
}
Hano函数里的ABC和我们输入的a,b,c不是一个变量,Hano里的ABC代表的是你指定的起始位目标位。但是计算机并不知道位关系会变化,所以需要我们更改指定的目标位和起始位,来实现中间的过度步骤。
青蛙跳台阶
一只青蛙可以一次跳 1 级台阶或一次跳 2 级台阶,例如:跳上第一级台阶只有一种跳法:直接跳 1 级即可。跳上两级台阶,有两种跳法: 每次跳 1 级,跳两次; 或者一次跳 2 级.问要跳上第 n 级台阶有多少种跳法?
从上图可以得出,青蛙一共有多少种跳法就是他有多少种路线。当n=3时,青蛙最后一次跳的时候有两种可能,一种是最后一次跳了1级,一种是最后一次跳了两级,n=4时同理。这个时候我们不管青蛙前面是怎么跳的,只需要把最后一步跳1级的所有可能和最后一步跳2级的所有可能都加起来,以此类推下去,到第一步或者第二步的时候我们就确切的知道了青蛙有几种跳法。这样就将问题就简单了。
n=n时,假设有F(n)种跳法,那分解后就变成了(F(n-1)+F(n-2))种跳法,以此类推,一直到n=1或n=2。n=1就只有一种跳法,n=2有两种跳法,所以跳法多少和n大小相同,返回值为n就ok;
#include<stdio.h>
int gua(int n){
int sum;
if (n>2) {
sum = gua(n-1)+gua(n-2);
}else if(n>0&&n<=2){
return n;
}
return sum;
}
int main(){
int n,sum;
printf("请输入青蛙跳的台阶总数:");
scanf("%d", &n);
sum=gua(n);
if (sum!=0) {
printf("跳法总数为: %d\\n",sum);
}
return 0;
}
熟悉斐波那契数列的同学可能已经看出来了这就是一个斐波那契数列。而斐波那契数列的每一项的值就是前两项的和,设f(n)为数列第n项的值,则f(n)=f(n-1)+f(n-2),道理都是一样的。
以上是关于C语言汉诺塔与青蛙跳台阶——递归的简单应用的主要内容,如果未能解决你的问题,请参考以下文章