问题讲述:
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。(只是其中一个故事)
问题简化:
有三根柱子 标号为 A B C
三个圆盘都在A柱上需移动到C柱
- 我们首先之只考虑有三个圆盘
按照惯性思维 移动思路为
- A—>C
- A—>B
- C—>B
- A—>C
- B—>A
- B—>C
- A—>C
- 当A柱上有四个圆盘时
- A->Bs
- A->C
- B->C
- A->B
- C->A
- C->B
- A->B
- A->C
- B->C
- B->A
- C->A
- B->C
- A->B
- A->C
- B->C
经过观察我们发现按照现在的思路找不到一些能够用到的规律,当圆盘数量为奇数或者偶数时第一步移动的都是不一样的接下来的也均不相同如果我们依然按照从上往下一块块移动的思想当然是不靠谱的。我试了一下我添加了好多判断但是当圆盘数量越多时问题越严重,所以我们要换一种思路
递归+逆推
之前我们从上往下考虑有问题那我们换成从下往上考虑,首先我们考虑最后一块,如果我我们想要将最后一块移动到C柱那么我们需要将其上面的n-1快全都移动到B柱。我们想移动倒数第二块(B柱上的最后一块)那我们需要将上面n-2块移动到A柱以此类推如果用这种思想那没我们最后发现只需要关注 我们移动到那一块,我们要将它上面的多少快移动到那根柱子上 这两点就可以了
JAVA程序
/**
*a ,b ,c 代表三根柱子
*可以理解为将a柱上第n快圆盘借助b柱移动到c柱上
*n 当前要移动的圆盘
*/
public void move(char a,char b,char c,int n){
if(n==1){
System.out.println(a+"->"+c);//如果当前为最上面的圆盘 那我 直接将 a 柱上的移动到c柱
}else{
move(a,c,b,n-1);
//可以理解为圆盘数量的奇偶判断 刚我们分析过当圆盘为奇数个时我们先移动到C柱当圆盘为偶数时移动到B柱
System.out.println(a+"->"+c);
//我们继续观察刚才我们对3个圆盘和四个圆盘时分析的结果,我们发现每当我们从主柱(当前移动的主子上的圆盘数量>=2 自定义)上移动了一圆盘到一个柱子上时,一定会移动下一个圆盘到另一个柱子上。
move(b,a,c,n-1);
//我们发现当我们将圆盘按照我们的思路移动到c上时,该圆盘上的所有圆盘也移动到了另一根柱子上即当前变量b代表的柱子
//上,为了让我们接下来可以继续移动下一根柱子我们需要将b柱上的所有圆盘移动到c上
}
}
注:a b c 是变量 存放的是 A B C 三根柱子根据不同情况存储不同的柱子 区分大小写。