图解汉诺塔

描述

在三个柱子之间移动盘子,一次只能移动一个,并且要保证每一步上边的盘子都要比下边的盘子小,最终实现把所有的盘子都从最左边柱子移动到最右边的柱子上。

解析

柱子A B C

一个盘子

只有一个盘子的时候,就比较简单了。如图,只需要一步,直接把 第 1 个盘子从 A移动到 C就完成了。

二个盘子

把第1个盘子从A移到B
把第2个盘子从A移到C
把第1个盘子从B移到C

三个盘子

把第1个盘子从A移到C
把第2个盘子从A移到B
把第1个盘子从C移到B
把第3个盘子从A移到C
把第1个盘子从B移到A
把第2个盘子从B移到C
把第1个盘子从A移到C

n个盘子

通过前面的三个例子,我们可以发现,盘子的移动是有规律可循的。

在每一步盘子移动的过程中,总会有一步,是下边最大的盘子,从 A 移到 C 的。如,两个盘子,就是第 2 个盘子从 A移到 C,三个盘子,就是第 3 个盘子从 A 移到 C。

仔细观察,以三个盘子为例,把第 3 个盘子从 A 移动到 C 这一步,其实,第 1 个和第 2 个盘子是已经按顺序摆放好了的,即一起放在中间的 B 柱子。

4个盘子,整个过程可以表述为:

把1,2,3盘子整体从 A 移到 B (可以认为是借助 C 柱子移动的),
把第 4 个盘子从 A 移到 C(不需要借助额外的柱子),
把1,2,3盘子整体从 B 移到 C(借助 A 柱子)

代码

public static void main(String[] args) {
        int n = 3;
        char a = 'A', b = 'B', c = 'C';
        hanio(n, a, b, c);
    }

    /**
     * @param n 一共需要移动的盘子
     * @param a 盘子移动的起始柱子
     * @param b 借助的柱子
     * @param c 盘子需要移动到的目标柱子
     */
    public static void hanio(int n, char a, char b, char c) {
        //只有一个盘子的时候,就直接从A移到C
        if (n == 1) {
            move(n, a, c);
        } else {
            //三步曲,注意观察,a,b,c三个的位置变化
            //1.把 n-1 个盘子看成一个整体,借助 C 从 A 移动到 B
            hanio(n - 1, a, c, b);
            //2.把第 n 个盘子从 A 移动到 C
            move(n, a, c);
            //3.再把 n-1 盘子整体,借助 A 从 B 移动到 C
            hanio(n - 1, b, a, c);
        }
    }

    public static void move(int n, char a, char b) {
        System.out.println("把第" + n + "个盘子从" + a + "移到" + b);
    }

 

posted on 2020-03-24 16:14  反光的小鱼儿  阅读(137)  评论(0编辑  收藏  举报