java实现汉诺塔(递归)

/**
 * 〈一句话功能简述〉
* 〈功能详细描述〉 * * @author wangzha * @see [相关类/方法](可选) * @since [产品/模块版本] (可选) */ public class HanoiTower { public static void hanoi(int n, String a, String b,String c) { if (n == 1) { // 只有一个圆盘时直接从A石柱移动到C石柱 move(n, a, c); } else { // 将前n-1个圆盘从石柱A移动到石柱B hanoi(n - 1, a, c, b); // 将第n号圆盘从石柱A移动到石柱C move(n, a, c); // 将前n-1个圆盘从石柱B移动到石柱C hanoi(n - 1, b, a, c); } } public static void move(int n, String i, String j) { System.out.println("第" + n + "个圆盘," + "从" + i + "移动到" + j); } public static void main(String[] args) { hanoi(2,"A","B","C"); } }

存在A、B、C大小形同的3根石柱,其中A石柱从下往上按照大小顺序依次摆放着n个盘子,现在需要将A石柱的盘子全部移动到C石柱上,并且每次只能移动一个圆盘,小圆盘不能放在大圆盘上,请问该如何移动?
java实现汉诺塔(递归)_第1张图片

算法分析:
当n=1时,也就是刚开始A石柱上仅仅摆放一个圆盘,那么直接将圆盘从A石柱上移动到B石柱上即可。
  当n=2时,从上往下按照大小顺序将圆盘编为1号和2号,那么要将圆盘全部从石柱A移动到石柱C,首先需要将1号圆盘移动到石柱B,再将2号圆盘移动到石柱C,最后将1号圆盘移动到石柱C。
  当n=3时,仍然从上往下按照大小顺序将圆盘编为1号、2号和3号,此时由于问题相对复杂,所以1号和2号圆盘看做一个圆盘,即1+2号圆盘,此时需要解决的就是将1+2号圆盘和3号圆盘移动到石柱C的问题,即先将1+2号圆盘移动到石柱B,再将3号圆盘移动到石柱C,最后将1+2号圆盘移动到石柱C即可。
  由于每次只能移动一个圆盘,那么如果要将1+2号圆盘移动到石柱B,需要将1+2号圆盘拆分为两个个体,看做将1号和2号圆盘移动到石柱B,同理将1+2号圆盘移动到石柱C。
  以此类推……
  当n=n时,将圆盘自上向下编为1号、2号、3号……n号,同理将1号到n-1号圆盘看做一个圆盘,即 ∑n1(n−1)号圆盘,此时解决的就是将 ∑n1(n−1)号圆盘和n号圆盘移动到石柱C的问题,即先将∑n1(n−1)号圆盘移动到石柱B,再将n号圆盘移动到石柱C,最后将∑n1(n−1)号圆盘移动到石柱C。因为将第n号圆盘移动到石柱C后,无论前n-1个圆盘怎么移动,都不需要再次移动第n号圆盘,即父问题与子问题相对独立且互不影响,因此可以将∑n1(n−1)号圆盘的问题同理向下拆分移动。

n=1时
第1个圆盘,从A移动到C
n=2时
第1个圆盘,从A移动到B
第2个圆盘,从A移动到C
第1个圆盘,从B移动到C
n=3时
第1个圆盘,从A移动到C
第2个圆盘,从A移动到B
第1个圆盘,从C移动到B
第3个圆盘,从A移动到C
第1个圆盘,从B移动到A
第2个圆盘,从B移动到C
第1个圆盘,从A移动到C

总结:
n个盘子和2个盘子或是3个盘子解决问题的形式都是一样的
将n-1个盘子有序地移动到B柱子上
将第n个盘子移动到C
将n-1个盘子从B柱子移动到C (这一步其实和将n-1个盘子从A柱子移动到C解决问题的形式是一样的)

假设是10个盘子从A移动到C。
按照分治思想,我们分解问题。
10个盘子从A移动到C = 9个盘子从A移动到B,1个盘子从A移动到C,9个盘子从B移动到C
=8个盘子从A移动到C,1个盘子从A移动到B,8个盘子从A移动到B,1个盘子从A移动到C,
8个盘子从B移动到A,1个盘子从B移动到C,8个盘子从A移动到C

注意:
10个盘子从A移动到C
9个盘子从A移动到B
8个盘子从A移动到C
等等这些过程将大问题拆分,直到拆分从1个盘子从某个柱子移动到另一个柱子
完全符合分治策略的特质。

你可能感兴趣的:(Java源代码)