递归求解汉诺塔问题

问题 2056: 汉诺塔

递归求解汉诺塔问题
分析:

汉诺塔:汉诺塔(Tower of Hanoi)源于印度传说中,大梵天创造世界时造了三根金钢石柱子,其中一根柱子自底向上叠着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。 --引用*

问题看起来似乎并不复杂,当1号柱子上只有一个盘子时只要把那个盘子直接移到3号柱子就行了,

有两个盘子的话把1号盘先移到2号柱子柱,再把2号盘移到3号柱,最后把2号柱上的1号盘移到3号柱就行了,

但现在如果要移动的盘子数量多了,要是我们自己手动操作,那画面会很美,(闲着无聊的人可以试试)。

假设要移动n个盘子,

我们先把上方的n-1个盘子看成整体,这下就等于只有两个盘子(n和上面n-1个构成的“一个”),自然很容易了,我们只要完成两个盘子的转移就行了。
现在我们先不管第n个盘子(最后一个盘子)。
假设1号柱子只有n-1个盘子,那么与之前一样的解决方式,将前n-2个盘子看成一个整体,先完成移动目标。
…………

就这样一步步向前找到可以直接移动的盘子,n,n-1,n-2,…,2,1,最终,最上方的盘子是可以直接移动到3号柱子的,那就好办了,我们的2号盘也能完成向3号柱子的转移,这时3号柱子上是已经转移成功的2个盘,于是3号盘也可以了,一直到第n号盘。

下面是Java代码:

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();//盘子的数量(n<=10)
		hanoi(n,1,2,3);
	}

	/**
	 * 递归实现汉诺塔问题
	 * @param n 盘子的数量
	 * @param a 起始柱
	 * @param b 中转柱
	 * @param c 目标柱
	 */
	private static void hanoi(int n,int a, int b,int c) {
		if(n == 1) {//递归的终止条件
			System.out.printf("Move %d from %d to %d\n",n,a,c);
		}else {
			hanoi(n-1, a, c, b);//将a柱子上的n-1个盘移到b柱子上
			System.out.printf("Move %d from %d to %d\n",n,a,c);
			hanoi(n-1, b, a, c);//将b柱子上的n-1个盘子移到c柱子上
		}
	}

}