汉诺塔问题的迭代与递归实现

  1 /**
  2  * @author http://www.cnblogs.com/Xuxy1996/p/8933056.html
  3  * @author xuxy
  4  *
  5  */
  6 public class second {
  7 
  8     /**
  9      * 实现碟子的从x移动到y
 10      * 
 11      * @param n
 12      *            n号碟子
 13      * @param x
 14      *            起始位置
 15      * @param y
 16      *            终点位置
 17      */
 18     private static void move(int n, int x, int y) {
 19         System.out.println(n + ":" + (char) (x + 65) + "---->" + (char) (y + 65));
 20     }
 21 
 22     /**
 23      * 理解 递归实现汉诺塔 核心在于,从最底层碟子的终点位置出发,举个例子:
 24      * 假如存在4个碟子,ABC3个柱子,为了把4号碟子移动到C柱子,那么需要将123碟子移动到B柱子才能确保4号碟子的顺利移动;
 25      * 现在问题规模减一,如何把123碟子移动到B柱子,思想同上,为了把3号碟子移动到B柱子,此时需要把12碟子移动到C柱子,
 26      * 最后,为了把2号碟子移动到C柱子,需要把1号碟子移动到B柱子;
 27      * 总的来说就是,当n号碟子需要X柱子的时候,剩余的n-1号碟子就应该从起始柱子出发移动到Y柱子.
 28      * 
 29      * @param num
 30      *            当前碟子编号
 31      * @param ABC
 32      *            柱子的位置
 33      */
 34     public static void hanoi_1(int num, int A, int B, int C) {
 35         if (num == 1)
 36             move(num, A, C);
 37         else {
 38             hanoi_1(num - 1, A, C, B);
 39             move(num, A, C);
 40             hanoi_1(num - 1, B, A, C);
 41         }
 42     }
 43 
 44     /**
 45      * 迭代实现汉诺塔问题 其实在本质上也是使用了递归,只不过这个递归栈是自己在操作,而不是系统
 46      * 同样的,参考上边的递归算法,对于最大的碟子,我们需要做的是先处理下一级的小碟子们,
 47      * 需要注意的一点是,栈是先进后出的,所以相比递归汉诺塔,这里的处理碟子的顺序需要相反,举个例子: 前提:2个碟子,3根柱子ABC,
 48      * 在上边的递归算法中,为了2号碟子移动到C柱子,需要把1号碟子移动到B柱子,等2号碟子移动到C柱子以后,1号碟子再移动到C柱子
 49      * 为了实际满足上边的顺序,所以压栈顺序应该是反过来的: 1 B->C
 50      *                                       2 A->C
 51      *                                       1 A->B;
 52      * 
 53      * @param num
 54      *            待处理碟子数目
 55      * @param ABC
 56      *            柱子位置
 57      */
 58     public static void hanoi_2(int num, int A, int B, int C) {
 59         Stack<data> stack = new Stack<data>();
 60         stack.push(new data(num, A, B, C, num));
 61         while (!stack.isEmpty()) {
 62             data d = stack.pop();
 63             A = d.x;
 64             B = d.y;
 65             C = d.z;
 66             num = d.num;
 67             if (num == 1)
 68                 move(d.number, A, C);
 69             else {
 70                 stack.push(new data(num - 1, B, A, C, num - 1));
 71                 stack.push(new data(1, A, B, C, num));
 72                 stack.push(new data(num - 1, A, C, B, num - 1));
 73             }
 74         }
 75     }
 76 
 77     /**
 78      * 在栈中保存碟子的当前状态的数据结构
 79      * 
 80      * @author xuxy
 81      *
 82      */
 83     private static class data {
 84         public data(int n, int a, int b, int c, int m) {
 85             num = n;// 剩余碟子数目
 86             x = a;// 起始位置
 87             y = b;// 中间位置
 88             z = c;// 终点位置
 89             number = m;// 当前碟子编号
 90         }
 91 
 92         int num, x, y, z, number;
 93     }
 94 
 95     /**
 96      * static 方法用于测试数据
 97      * 
 98      * @param args
 99      */
100     public static void main(String[] args) {
101         Scanner sc = new Scanner(System.in);
102         int num = sc.nextInt();
103         hanoi_1(num, 0, 1, 2);
104         System.out.println("------------------------------");
105         hanoi_2(num, 0, 1, 2);
106     }
107 
108 }

猜你喜欢

转载自www.cnblogs.com/Xuxy1996/p/8933056.html