简单递归解决汉诺塔(跟着我的思路来,肯定拿下)

什么是汉诺塔

汉诺塔,是一个源于印度古老传说的益智玩具。传说中,大梵天在创造世界时制作了三根金刚石柱子,并在一根柱子上按照大小顺序摞着64片黄金圆盘。随后,大梵天命令婆罗门将圆盘从下面开始按大小顺序重新摆放在另一根柱子上,同时规定,在小圆盘上不能放大圆盘,且在三根柱子之间每次只能移动一个圆盘。
在这里插入图片描述

即在三根柱子间移动圆盘,但要保持大圆盘始终在小圆盘下面。

递归处理的本质

递归本质是把⼀个⼤型复杂问题层层转化为⼀个与原问题相似,但规模较⼩的⼦问题来求解;直到⼦问题不能再被拆分,递归就结束了。所以递归的思考⽅式就是把⼤事化⼩的过程。
接下来我举一个例子。

int fac(int x)//求阶乘
{
	int y;
	if(x>0)
	{
	    y = x;
		y *= fac(x - 1);
		return y;
	}
	if (x == 1)
		return x;

}
int main()
{
	int x = 4;
	printf("%d ", fac(x));
}

在此个简单的求阶乘函数中,我们一眼就能判断出该函数运用了递归(即自身调用了数次fac()函数)。
在这里插入图片描述
通过以大化小的方法,我们第一次能得到的确切值一定是fac(1)所得的结果1。

解决汉诺塔

那么回归汉诺塔,我们假设有A,B,C三根柱子,n个盘子。
有n个盘子,一定是将大化小,将前面的n-1个从A移到B,第n个从A移到C。
在这里插入图片描述

有n-1个盘子,一样将前面的n-2个从B到A,第n-1个从B到C。
在这里插入图片描述
这样我们就不难发现一个规律。除了最下面的盘子一直移到C以外,其它盘子一直在A柱和B柱一直来回切换。
那么各位王子公主请看代码(一部分):

void tower(char a, char b, char c,int x)
{
		tower(a, c, b, x - 1);//将A座上的n-1个盘子借助C座移向B座
		//注意上面的n-1和下面的n-1不同,它们是基于当前状态所产生的
		//假如上面代码有六个盘子那么就是将五个从A移向B
		//下面代码的n-1可能为4,3,2,1等
		//形式相同不要判断错误了
		tower(b, a, c, x - 1);//将B座上的n-1个盘子借助A座移向C座
}
int main()
{
	char a = 'A';//三个字符三根柱子
	char b = 'B';
	char c = 'C';
	int x;
	printf("有多少层汉诺塔:");
	scanf("%d", &x);
	tower(a, b, c, x);
	return 0;
}

而后,我们肯定要输出吧,并且递归还要有一个限制条件吧。那我们再完善一下

void tower(char a, char b, char c,int x)
//这里要理解我们这个代码的构造了,
//我们的第一个字符变量是指放有n个盘子的柱子,
//第二个字符变量是我们的中转站要借助它来转移盘子,
//第三个字符变量是我们要移动盘子到达的柱子
{
	if (x == 1)//当循环到最后一次
	{
		printf("%c--->%c\n", a, c);
	}
	else
	{
		tower(a, c, b, x - 1);//此部分函数处理A柱和B柱上的盘子互相转移
		printf("%c--->%c\n", a, c);
		//我们这个printf是根据这个void tower(char a, char b, char c,int x)函数来的创建的,
		//根据我们上面的代码理解肯定是要从第一个字符移动到第三个字符变量上。此部分的a跟c也会随着函数变量的变化而变化(上面和下面的递归的函数字符变量的位置都改变了),
		//所以说大家不用担心它会循环出现a->c.
		tower(b, a, c, x - 1);//此部分实现将A柱和B柱上的最后一个盘子放到C柱上
	}

}
int main()
{
	char a = 'A';
	char b = 'B';
	char c = 'C';
	int x;
	printf("有多少层汉诺塔:");
	scanf("%d", &x);
	tower(a, b, c, x);
	return 0;
}

总代码

void tower(char a, char b, char c,int x)
{
	if (x == 1)
	{
		printf("%c--->%c\n", a, c);
	}
	else
	{
		tower(a, c, b, x - 1);
		printf("%c--->%c\n", a, c);
		tower(b, a, c, x - 1);
	}

}
int main()
{
	char a = 'A';
	char b = 'B';
	char c = 'C';
	int x;
	printf("有多少层汉诺塔:");
	scanf("%d", &x);
	tower(a, b, c, x);
	return 0;
}

不太深究的话,王子公主们看看我的代码大家有没有感觉有点道理。有什么问题请多多指教啦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明fei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值