分治算法解决汉诺塔问题
分治算法解决汉诺塔问题
我们将 3 个柱子分别命名为起始柱、目标柱和辅助柱。实际上,解决汉诺塔问题是有规律可循的:
-
当起始柱上只有 1 个圆盘时,我们可以很轻易地将它移动到目标柱上
-
当起始柱上有 2 个圆盘时,移动过程如下图所示:
-
当起始柱上有 3 个圆盘时,移动过程如图 ,仔细观察会发现,移动过程和 2 个圆盘的情况类似:先将起始柱上的 2 个圆盘移动到辅助柱上,然后将起始柱上遗留的圆盘移动到目标柱上,最后将辅助柱上的圆盘移动到目标柱上。
- 将起始柱上的 n-1 个圆盘移动到辅助柱上;
- 将起始柱上遗留的 1 个圆盘移动到目标柱上;
- 将辅助柱上的所有圆盘移动到目标柱上。
由此,n 个圆盘的汉诺塔问题就简化成了 n-1 个圆盘的汉诺塔问题。按照同样的思路,n-1 个圆盘的汉诺塔问题还可以继续简化,直至简化为移动 3 个甚至更少圆盘的汉诺塔问题。
1个圆盘的次数 2的1次方减1
2个圆盘的次数 2的2次方减1
3个圆盘的次数 2的3次方减1
。 。 。 。 。
n个圆盘的次数 2的n次方减1
故:移动次数为:2^n - 1
实现代码
/**
* @author qxL
* @create 2021-09-22 14:47
*/
public class HanoTower {
public static void main(String[] args) {
move(5, 'A', 'B', 'C');
}
public static void move(int num, char a, char b, char c) {
//如果只有一个盘, num ==1
if (num == 1) {
System.out.println("第1个盘子从 " + a + "->" + c);
} else {
//如果有多个盘,可以看作两个,最下面的一个,和最上面的全部
move(num - 1, a, c, b);//把a所有的盘从a移动到b,借助c
System.out.println("第" + num + "个盘子从" + a + "->" + c);
move(num - 1, b, a, c);//把b所有的盘从b移动到c,借助a
}
}
}