描述
在三个柱子之间移动盘子,一次只能移动一个,并且要保证每一步上边的盘子都要比下边的盘子小,最终实现把所有的盘子都从最左边柱子移动到最右边的柱子上。
解析
柱子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); }