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
今日推荐
周排行