什么是汉诺塔问题?
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
汉诺塔问题的约束条件?
1、每次只能从某个柱子的最上面移动一个盘子;
2、任何盘子可以从任何柱子搬到其他柱子;
3、直径较小的盘子永远必须放在直径较大的盘子之上。
汉诺塔问题算法思想?
采用递归:只有将最大圆盘之上的其余盘子移动到辅助柱子上,之后才可以将最大圆盘移动到目标柱子上。
假设A柱子上有n个圆盘。
1、将A柱子上除最大盘之外的 n-1个盘 借助C柱子 移动到B柱子上;
2、将A柱子把剩下的“第n”个最大盘直接移动到C柱子上;
3、B柱子 共n-1个盘借助 A柱子移动到C柱子;这一步就相当于是源柱子由A变换到了B上,同时辅助柱子B->A
实现代码
public class Main {
//记录移动的总次数,这里也可以使用num = f(n) = 2^n-1来获得移动的次数
private static int count = 0;
//采用StringBuffer避免使用String的拼接来获得结果元素
private static StringBuffer results = new StringBuffer();
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
hanoi(n,'A','B','C');
System.out.println(count);
for (String result : results.toString().split("-")) {
System.out.println(result);
}
}
/**
* 汉诺塔算法,将盘子从柱子A移动到C
* @param n 盘子的总数
* @param A 源柱子
* @param B 辅助柱子
* @param C 目标柱子
*/
public static void hanoi(int n, char A,char B,char C){
count++;
if(n==1){
//代表移动了盘子
results.append(n +" from "+A+" to "+C+"-");
}else{
//注意参数的位置变化
hanoi(n-1,A,C,B);
//代表移动了盘子
results.append(n +" from "+A+" to "+C+"-");
hanoi(n-1,B,A,C);
}
}
}