汉诺塔:
又称河内塔,是一个源于印度古老传说的益智游戏。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
思路:
这里我们命名3根柱子分别为A,B,C,圆盘在A柱上,移动到C柱。
先看几种简单的情况:
(首先这里ABC可以称为起始柱、临时柱、终点柱。)
n=1时:直接移动到C。
n=2时,移动过程如下:
可表示为: A->B A->C B->C
n=3时,移动过程如下:
可表示为:A->C A->B C->B A->C B->A B->C A->C
其中需要注意的一点是:在n=3时,要从A移动3个圆盘到C上,途中会经历2个圆盘在B上的时候。如下图:
这个时候其实就是n=2时候的操作,只是现在临时柱变成了A,同理,如果是n=5,途中会经历的情况:
把最大圆盘移动到C,这里也就是n=4时候的操作。
所以总结思路:n个圆盘的时候,第一个目标是把n-1个盘子移动到临时柱上,然后第二目标把1最大圆盘移动到终点柱上,最后再把n-1移动到终点柱上完成最终目标。
如果n=5。便是前4移到临时柱上,在把最大圆盘1移动到终点柱上,再把前4移到终点柱上,便可实现最终目标。
那么是怎么把前4分别移到临时柱和终点柱的呢,那么便是把前3移到临时柱上,在把前最大圆盘1移动到终点柱上,再把前3移到终点柱上……直到分别把前1移到临时柱上,在把前最大圆盘1移动到终点柱上,再把前1移到终点柱上(到1可以直接移动过去)。
如下:
1.父问题和子问题是一样的事,且不断简单。2.有一个化简为非递归状态的出口。所以可以用递归。
代码如下:
public class HanNuoTa {
public static void main(String[] args) {
while (true){
System.out.println("玩几层汉诺塔");
int n=new Scanner(System.in).nextInt();
f(n);
}
}
private static void f(int n) {
f(n,"A","B","C");//n代表圆盘个数 A,B,C分别代表3个柱子
}
private static void f(int n, String from, String mid, String to) {//from起始柱 mid临时柱 to终点柱
if(n==1){//结束条件,到1触底结束
System.out.println(from+"->"+to);
return;
}
f(n-1,from,to,mid);//n-1个 A->B
f(1,from,mid,to);//最大一个 A->C
f(n-1,mid,from,to);//n-1个 B->C
}
}
代码执行过程: