C语言之汉诺塔问题解答(递归方法)

目录

一. 首先,何为汉诺塔问题?

二.解题思路

三.代码实现

四。完整代码展示


一. 首先,何为汉诺塔问题?

简单来讲,汉诺塔问题是这样的:

​ 给定三根柱子,记为A  B C ,其中 A柱子上有 n个盘子,从上到下编号为 0 到 n−1 ,且上面的盘子一定比下面的盘子小。问:将 A柱上的盘子经由 B 柱移动到 C 柱最少需要多少次?

​ 移动时应注意:① 一次只能移动一个盘子

​ ②大的盘子不能压在小盘子上

二.解题思路

用递推的方法,我们需要先确定ABC三个柱子的角色,A是起始位置,B是中转位置,C是目的位置。然后再考虑如何将A上的所有盘子移动到C上,又得随时保证大盘子在下面小盘子在上面,那么我们要思考如何将最大的盘子先放到C上。

我们先拿最简单的一层汉诺塔做例子,我们只需要将盘子直接由A移动到C就可以了。

我们再拿三层汉诺塔做例子,我们先将最小的盘子移动到C,再将中盘子移到B,再将小盘子移动到B,再将大盘子移动到C盘子,再将小盘子移动到A,最后将中,小盘子按大小放到C,到此三层汉诺塔问题就解决了。

由上面两个例子可以看出一层就汉诺塔最特殊,可以看作单独一个和二层汉诺塔以上的作区分,我们观察二层以上汉诺塔也可以得到一个规律 :假设有n层汉诺塔,我们只需要将一次将n-1到第1个盘子到都放到B上,再将第n个盘子放到C上,最后将其他盘子依次都放到C上就好了。

三.代码实现

根据上面这些我们就可以写一个函数来定义这两种情况

void hanoi(int n,char a,char b,char c)//a,b,c为汉诺塔的柱子数
{
	void move(char x, char y);
	if (n == 1)//第一层情况
	{
		move(a, c);
	}
	else//其他层数情况
	{
		hanoi(n - 1, a, c, b);
		move(a, c);
		hanoi(n - 1, b, a, c);
	}
}

我们还需要写一个函数来描述盘子的移动路径

void move(char x, char y)
{
	printf("%c-->%c\n", x, y);
}

最后我们再把主函数写出来就好了。

    void hanoi(int n, char a, char b, char c);
	int m;
	printf("input the number of desks:");//输入层数
	scanf("%d", &m);//输入层数
	printf("the step to move %d desk:\n", m);//输出移动步骤
	hanoi(m, 'A', 'B', 'C');

四。完整代码展示

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void hanoi(int n,char a,char b,char c)
{
	void move(char x, char y);
	if (n == 1)//第一层情况
	{
		move(a, c);
	}
	else
	{
		hanoi(n - 1, a, c, b);
		move(a, c);
		hanoi(n - 1, b, a, c);
	}
}
void move(char x, char y)
{
	printf("%c-->%c\n", x, y);
}
int main()
{
	void hanoi(int n, char a, char b, char c);
	int m;
	printf("input the number of desks:");
	scanf("%d", &m);
	printf("the step to move %d desk:\n", m);
	hanoi(m, 'A', 'B', 'C');
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值