勤时当勉励 岁月不待人
C/C++ 游戏开发
Hello,这里是君兮_,今天更新一篇我一直想更但是一直没空写的博客——汉诺塔问题,在所有有关递归的问题中,汉诺塔问题是最经典的问题之一,可以说,如果你能真正理解汉诺塔问题的内核,你的递归也一定不会太差,今天就来带大家深入浅出汉诺塔问题。
深入浅出汉诺塔问题
- 什么是汉诺塔?
- C语言实现汉诺塔
- 具体解决汉诺塔问题思路分析
- 当需要A上需要移动的盘子n=2时
- 当需要A上需要移动的盘子n=3时
- 当需要A上需要移动的盘子n=4时
- 当需要A上需要移动的盘子为n时
- 实现汉诺塔问题的代码
- 总结
什么是汉诺塔?
- 汉诺塔(Tower of Hanoi)源自印度古老传说的一个游戏,大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,并且在移动时三根柱子之间一次只能移动一个圆盘。
C语言实现汉诺塔
具体解决汉诺塔问题思路分析
-
从上面的对于汉诺塔问题的说明我们可以得到这样一个结论
-
如果要把A柱上的盘子全部都移动到C柱上,要遵循以下规则:
-
1.每次只能移动A柱最上面的一个盘子
-
2.小盘子上不能放大盘子。
我们来一步一步分析,首先设此时A中有n个盘子,我们现在的目标是借助B柱把A上的盘子全部移动到C柱上
当需要A上需要移动的盘子n=2时
- 这个很简单我就不画图啦!
- 我们只需要先把A最上面的盘子移到B上,再把A另一个盘子移到C上,最后把B上盘子移到C上即可。
当需要A上需要移动的盘子n=3时
- 将2个盘子从A移动到B上。重复n=2时的步骤,此时是将那2个盘子从A借助C移动到B
- 接着,把A上的盘子移动到C上
- 将B上的2个盘子移动到C上。重复n=2时的步骤,此时是将那2个盘子从B借助A移动到C
当需要A上需要移动的盘子n=4时
-
将3个盘子从A移动到B上。重复n=3时的步骤,与n=3不同之处在于,我们此时是借助C把A上盘子移到B
-
将A上最后一个盘子移动到C上
-
将B上的3个盘子移动到C上。重复n=3时的步骤,与n=3不同之处在于,我们此时是借助A把B上盘子移到C
当需要A上需要移动的盘子为n时
- 怎么样,经过上面的讲解你发现规律了吗?
- 也就是说,对于任意一个大于1的正整数n,如果有一个n层汉诺塔的问题,我们就可以将之分解为两个n-1层汉诺塔问题求解
实现汉诺塔问题的代码
-
通过我们上面的分析,我们就可以把这个问题看成这三步:
-
1.将A上n-1层的盘子通过C移动到B上
-
2.将此时A上剩余的盘子移动到C上
-
3.将B上此时n-1层的盘子通过A移动到C上
- 参考代码如下:
#include<stdio.h>
void Move (char A, char C, int n)
{
printf("把第%d个盘子从%c--->%c\n", n, A, C);
}
void HanoiTower(char A, char B, char C, int n)
{
if (n == 1)
{
Move(A, C, n);
}
else
{
//将n-1个盘子从A柱借助于C柱移动到B柱上
HanoiTower(A, C, B, n - 1);
//将A柱最后一个盘子移动到C柱上
Move(A, C, n);
//将n-1个盘子从B柱借助于A柱移动到C柱上
HanoiTower(B, A, C, n - 1);
}
}
int main()
{
int n = 0;
printf("输入A柱子上的盘子个数:");
scanf("%d", &n);
//将n个盘子从A柱借助于B柱移动到C柱上
HanoiTower('A', 'B', 'C', n);
return 0;
}
总结
-
今天的内容暂时到这里就结束了,我们今天通过递归的方式具体解决了汉诺塔问题。如果你还有问题的话一定要自己试一下,不然光看是非常容易遗忘并且非常不容易理解的,咱们必须反复的练习才能熟悉起来!
-
好了,如果你有任何疑问欢迎在评论区或者私信我提出,大家下次再见啦!
新人博主创作不易,如果感觉文章内容对你有所帮助的话不妨三连一下这个新人博主再走呗。你们的支持就是我更新的动力!!!
**(可莉请求你们三连支持一下博主!!!点击下方评论点赞收藏帮帮可莉吧)**