汉诺塔/青蛙跳台阶(经典递归)

汉诺塔:
题目描述:一块板上有三根针 A、B、C。A 针上套有 64 个大小不等的圆盘,按照大的在下、小的在上的顺序排列,要把这 64 个圆盘从 A 针移动到 C 针上,每次只能移动一个圆盘,移动过程可以借助 B 针。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。从键盘输入需移动的圆盘个数,给出移动的过程
一个盘
我们先简化为一个盘,假设这个盘在A针,直接移动到C针 我们暂把这个过程定为move(A,C)
两个盘
当两个盘时
(注意:每次移动的都是针最上面的那个盘 所以不用指定盘的编号)
1)
A移到B,

A移到C,move(A,C)----------------------分界-------------------

B移到C。

三个盘
然而到三个盘时我们就只有一种解法了
A到C,
A到B,
C到B

A到C,move(A,C)----------------------分界-------------------

B到A,
B到C,
A到C

分界线上方我们可以看作从A针经由C针到B针

分界线下方我们可以看作从B针经由A针到C针

四个盘
A—B
A—C
B—C
A—B
C—A
C—B
A—B

A—Cmove(A,C)----------------------分界-------------------

B—C
B—A
C—A
B—C
A—B
A—C
B—C
分界线上方我们可以看作从A针经由C针到B针

分界线下方我们可以看作从B针经由A针到C针
与三盘时情况相同

总结

从三盘开始整个移动盘的过程可总结为三个大过程

hanoi(n-1,A,C,B)//从A针经由C针到B针
move(A,C)//
hanoi(n-1,B,A,C)//从B针经由A针到C针

如图所示:
在这里插入图片描述
如果想详细了解每个递归调用在堆栈中的详细过程请移步 B站,对初学者较为复杂。

对函数中每一个递归调用都看成只是一个简单操作,只要接口一致,必能实现规格说明中定义功能,切忌想的太深太远

代码如下:

#include <stdio.h>
void hanoi(int, char, char, char);
void move(char, char);
int main()
{
	int n;
	printf("Input the number of diskes:");
	scanf("%d", &n);
	printf("\n");
	hanoi(n, 'A', 'B', 'C');
	return 0;
}
void hanoi(int n, char A, char B, char C)
{
	if (n == 1)//当n等于1的时候直接从A移到C
		move(A, C);
	else
	{
		hanoi(n - 1, A, C, B);
		move(A, C);
		hanoi(n - 1, B, A, C);
	}
}
void move(char getone, char putone)
{
	printf("%c -> %c\n",getone, putone);
}

----------------------------------

青蛙跳台阶:
题目描述1:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

规律
分别列出当n=1,2,3,4,5,6,7…时青蛙跳台阶的方法个数
当n=1时:1种跳法
当n=2时:2种跳法(1,1)(2)
当n=3时:3种跳法(1,1,1)(2,1)(1,2)
当n=4时:5种跳法(1,1,1,1)(1,1,2)(2,2)(2,1,1)(1,2,1)
… … …
观察到:1+2=3;2+3=5… …
此为斐波那契数(唯一区别是a,b的初始值不一样)

此下为代码:

#include <stdio.h>
int Fab(int n)
{
	if (n < 3)
	{
		return n;
	}
	else {
		return Fab(n - 1) + Fab(n - 2);//相当于c=a+b
	}
}
int main()
{
	int n;
	scanf_s("%d", &n);
	printf("%d", Fab(n));
}

---------------------------------------------------------------------
题目描述2:一只青蛙一次可以跳上1级台阶,也可以跳上2级…也可以跳上n阶。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

规律
设跳上一个n阶台阶需要的方法数为jump(n)
当为n-1阶台阶且第一次跳一阶:jump(n-1)种跳法
当为n-2阶台阶且第一次跳一阶:jump(n-2)种跳法
当为n-3阶台阶且第一次跳一阶:jump(n-3)种跳法
当为n-4阶台阶且第一次跳一阶:jump(n-4)种跳法
… … …
当为1阶台阶且第一次跳一阶:jump(1)种跳法
即跳上n阶台阶的方法总数为jump(n):
=jump(n-1)+jump(n-2)+jump(n-3)+jump(n-4)+…+jump(1)
为此我们可以将其看作数学问题
先总结成一类通解易知为 jump(n - 1) * 2;

构造递归函数

#include <stdio.h>
int jump(int n)
{
	if(n<3)
	{
		return n;	
	}
	else
	{
		return jump(n - 1) * 2;//数学通式
	}
}
int main()
{
	int n=0;
	scanf("%d",&n);
	printf("%d",jump(n));
}

总结
1):大事化小

2):对函数中每一个递归调用都看成只是一个简单操作,只要接口一致,必能实现规格说明中定义功能,切忌想的太深太远

3):递归函数不要调用的太深否则会导致栈溢出

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值