递归求解汉诺塔问题(详细解答)

汉诺塔移动步数的计算

具体汉诺塔的规则大家自行百度吧,就不介绍了,这里介绍一下如何求解汉诺塔移动步数的计算思想。
当汉诺塔层数为一层时,很显然只需要一步,直接从A杆移动到C杆
在这里插入图片描述
当层数为两层时,则需要三步,先将第一个从A杆移到B杆,然后将第二个从A杆移到C杆,最后将第一个从A杆移到C杆,到这里有没有发现规律呢?
在这里插入图片描述
当层数为三层时,首先要把前两层移到B杆上,这样就可以把第三层移到C杆上了,然后再将这两层从B杆移到C杆上,上面讨论了,将两层汉诺塔从一个杆移动到另一个杆上面需要三步,所以当层数为三层时,就需要3+1+3也就是7步,我想到这里你应该发现规律了,汉诺塔移动步数的问题其实有着镜像的性质
当层数为4层时呢?
很显然,就是3+1+3+1+3+1+3也就是15步
……
当层数为n层时呢?
最终的结果就是 n-1层所需的步骤 + 1 + n-1层所需的步骤

到这里,我们发现这些完全符合递归的几个要素啊,所以可以尝试用递归求解。
首先是边界条件:也就是当n == 1时,这时候直接返回1,因为当汉诺塔层数为一层时,要用一步完成
然后是n-1层与n层的关系,刚才也找到了,就是n层的步骤等于 n-1层所需的步骤 + 1 + n-1层所需的步骤 ,也就是1+2*(n-1层所需步骤)
最后将这个关系用代码写出来

代码如下:

int my_hanoi(int num)
{
	if (num == 1)
	{
		return 1;
	}
	return 1 + 2 * my_hanoi(num - 1);//n-1与n的关系
}

int main()
{
	int num = 0;
	printf("请输入一个值:");
	scanf("%d", &num);
	int ret = my_hanoi(num);
	printf("%d层汉诺塔移动的步数为:%d", num, ret);
	return 0;
}

汉诺塔移动步骤的计算

举个四层的例子:(我说的可能会比较绕🤣)
在这里插入图片描述
若要移动四层,首先我们要做的时把上面三层从A杆借助C杆移到B杆上,然后再将第四层从A杆移动到C杆上,最后再把刚才的三层从B杆移动到C杆上,结束。
在这里插入图片描述

那么问题来了,怎么把最上面的三层移动到B杆上呢?为了完成这个问题,我们要先把三层上面的两层从A杆借助B杆移到C杆上,然后再把第三层从A杆上移动到B杆上,最后再把刚才的两层从C杆借助A杆移动到B杆上,结束。
那么问题就又来了,怎么把最上面的两层移动到C杆上呢,为了完成这个问题,我们首先将第一个从A杆移到B杆,然后将第二个从A杆移到C杆,最后将第一个从A杆移到C杆结束。
然后我们再依次返回,仅仅改变所要移动到目标杆就好了,返回到最后,我们就完成了四层的汉诺塔移动。
那n层的时候呢?
根据上面的思想,当我们要移动n层汉诺塔时,要先将上面的n-1层先从A杆借助C杆移动到B杆上,然后再将第n层移动到C杆上,最后再将刚才的n-1层从B杆借助A杆移动到C杆上,这样就完成了汉诺塔的移动。
同样的你可以尝试思考怎么移动n-1层呢?移动n-1层的时候,又涉及到移动n-2层,那怎么移动n-2层呢?n-3层呢?n-4层呢?……
想到最后,你会发现都是先通过移动第一层,来引导第二层的移动。再尝试去向,第一层最开始移动的方向是根据层数的奇偶性来的。

到这里我们发现这也符合递归的几个要素啊,所以同样可以尝试用递归求解
首先是边界条件:同样是当n == 1时,这时候我们直接输出,从A移动到C
然后是n-1层与n层的关系,我们刚才也找到了,当要移动n层汉诺塔时,要先将上面的n-1层先从A杆借助C杆移动到B杆上,然后再将第n层移动到C杆上,最后再将刚才的n-1层从B杆借助A杆移动到C杆上,这样就完成了汉诺塔的移动。
最后将这个关系用代码写出来

//可以这样理解递归函数的参数列表
//第一个参数:汉诺塔层数
//第二个参数:起始杆
//第三个参数:借助杆
//第四个参数:目标杆
void move(int n, char a, char b, char c)
{
	if (n == 1)
	{
		printf("%c --> %c\n", a, c);
		return 0;
	}
	move(n - 1, a, c, b);
	printf("%c --> %c\n", a, c);
	move(n - 1, b, a, c);
}

int main()
{
	int step = 0;
	printf("输入一个值:");
	scanf("%d", &step);
	move(step, 'A', 'B', 'C');
	return 0;
}

感谢你能看到这里🥰

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值