汉诺塔-图解详细
麦兜 / 2019-08-08 / 算法 / 阅读量 26686

题目:

(如果看过N次的就不用看了 直接跳到题解)
汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?

题解

当盘子只有1个

1.png
还是老规矩如果只有一个盘就从起始点直接移动到目标点 就算完成
2.png

当盘子有2个

3.png
第一步、首先要把第1个盘子移动到过渡点,才能把第2个盘子移动到目标点
4.png
第二步、可以调动第2个盘子移动到目标点
5.png
第三步、把过度点上的盘子移动到目标点就完成了。
6.png


高能预警!!!!

当盘子有2个以上

7.png
其实和之前2个盘子一样,“就三步”
可以把3个盘子分成两部分
N和N-1
8.png
第一步、把第N-1 移动到过度点 至于为什么可以这样移动你先不管(先把这个概念理解,后面就详解) 你就当第1个盘子和第2个盘子合成一个盘子了
9.png
第二步、把第N个盘子移动到 目标点
10.png
第三步、把“N-1” 这个 “二合一” 的盘子移动到目标点就好
11.png

开始详解为什么可以把“N-1” 第1个盘和第2个盘这样移动
首先想把 第1个盘和第2个盘移动到中间的柱子就需要改变一样东西。
把中间的柱子当成 目标点 第3根柱子便成为 过渡点
12.png
可以参考只有2个盘子的步骤思考一下,盘子是如何从起始点移动到目标点

聪明的你 我想应该已经猜到,还是那3步。

1、起始点->过渡点
2、起始点->目标点
3、过渡点->目标点

13.png
14.png
15.png
现在知道"N-1" 那个盘子为什么可以把当成两个盘子移动了吧。
其实就是一个递归思想,好了我们最终的目标是3个盘子都移动到第3根柱子
还原上一个“状态” 第3根柱子才是真正的目标点
16.png

这下子要把第3个盘子移动到 目标点
17.png
我们就剩一步了
思考一下 如何把过渡点的所有盘子移动到目标点

其实怎么都逃不过那“三部曲” 只是把起始点、过渡点、目标点调换了。
1、起始点->过渡点
2、起始点->目标点
3、过渡点->目标点

因为从第2根柱子移动到目标点 我就让他成为起始点 然后我们需要一根柱子借助移动,然而第三根已经有“名称了" 只能委屈”第一根柱子“成为过渡点

看好了 "三部曲又来了" 不过多少个盘子都还是逃不过这个。
19.png
20.png
21.png

代码示例:

#include<iostream>
#include<algorithm>
using namespace std;
void Hanoi(int n,char A,char B,char C)
{
    if (n == 1) /*当盘子为一个时候 直接把A到C的步骤打印出来就好*/
        cout << A << "->" << C<<endl;
    else{
           /*否则把起始点 过度点 目标点 互换*/
        Hanoi(n - 1, A, C, B);
        cout << A << "->" << C<<endl;
        Hanoi(n - 1, B, A, C);
        }
}
int main()
{
    Hanoi(1, 'a', 'b', 'c');
}
1 + 2 =
快来做第一个评论的人吧~