Hanoi(汉诺塔)问题

Hanoi问题的递归解法与代码分析

Hanoi(汉诺塔)问题

先简单介绍下游戏规则:

游戏规则很简单,有三个柱子,其中一个柱子上从下往上按顺序摆放着若干个圆盘,圆盘大小不一,大的圆盘在下,小的圆盘在上。玩家需要将圆盘按顺序变更到另一个柱子上,不能改变圆盘从小到大的顺序。

现在我们将三个盘子改成n个,要求我们编程解决。

#include<stdio.h>
void hanoi(int n, char ori ,char mid,char des)
{
	if (n == 1)
	{
		printf("%c-->%c\n", ori, des);
	}
	else
	{
		hanoi(n - 1, ori, des, mid);
		printf("%c-->%c\n", ori, des);
		hanoi(n - 1, mid, ori, des);
	}
}
int main()
{
	int n = 0;
	scanf_s("%d", &n);
	hanoi(n, 'A', 'B', 'C');
	return 0;
}

这是一个经典的递归的问题,我们将问题简化拆解,n个盘子(从上到下编号为1,2,3,…,n-1,n)我们将其上面的n-1个盘子看成一个盘子,就将问题简化成了两个盘子的hanoi问题。

现在我们就看如何让两个盘子从第一根柱子放在第三根柱子上,我们可以先把上面那个盘子放在第二个柱子上,然后把下面那个盘子放在第三根柱子上,最后我们将第二根柱子上的盘子(也就是上面的那个盘子),由第二根柱子放在第三根柱子上,这样我们就完成了任务。

我们解决这个问题的关键点是将上面的n-1个盘子当成一个盘子,但实际上它不是一个盘子,那我们怎么表示将上面的n-1移动到第二根柱子上面呢?那就是用递归。

下面我们分析下代码的编写

main函数中,我们先定义变量n,表示我们要将多少个盘子从第一根柱子移动到第三根柱子上.

然后调用函数hanoi.我们将四个实参传递给形参,n表示有n个多少个盘子,‘A’,‘B’,‘C’,表示三根柱子.

接下来我们来到hanoi函数,函数的定义中n是有多少个盘子,ori表示起始位置,mid表示中间位置,des表示目的位置,我们要将其从第ori移动到des.

在函数内,我们用一个if语句来作为递归结束的条件,当n=1时(即只有一个盘子时)我们将盘子从第一根柱子上移动到第三根柱子上.

因为我们不好将柱子画出来,所以我们用printf的形式打印出来,因为只有一个盘子我们直接将其从第一根柱子上移动到第三根柱子上,即printf:ori–>des的过程.

如果n!=1的话,我们进入else,就像上面所说我们将其分成n-1个和第n个,首先将n-1个盘子放在第二根柱子上,刚刚我们所说hanoi(n , ori, des, mid)表示将n个盘子从ori–>des的过程.所以它就可以表示为hanoi(n - 1, ori, des, mid)

下面的printf(“%c–>%c\n”, ori, des),并不是对n-1个盘子进行移动,因为我们说了一次只能移动一个盘子,而是对最底下的第n个盘子进行移动.

最后我们将其上面的n-1个盘子,从第二根柱子上放到第三根柱子上.

我们没有分析递归里面,但我们首先得先把这个函数的意思先弄明白 hanoi(int n, char ori ,char mid,char des),将n个盘子从ori移动到des上,那在递归中n-1个盘子也是一样的方式将n-1从起始位置移动到终点位置,都是一样的步骤,我们只需要将其想明白即可。

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值