modify code

master
algorithmzuo 2 years ago
parent 21499c1780
commit 489d28f3b5

@ -1,5 +1,6 @@
package class17; package class17;
import java.util.HashSet;
import java.util.Stack; import java.util.Stack;
public class Code02_Hanoi { public class Code02_Hanoi {
@ -87,41 +88,67 @@ public class Code02_Hanoi {
} }
public static class Record { public static class Record {
public boolean finish1; public int level;
public int base;
public String from; public String from;
public String to; public String to;
public String other; public String other;
public Record(boolean f1, int b, String f, String t, String o) { public Record(int l, String f, String t, String o) {
finish1 = false; level = l;
base = b;
from = f; from = f;
to = t; to = t;
other = o; other = o;
} }
} }
// 之前的迭代版本,很多同学表示看不懂
// 所以我换了一个更容易理解的版本
// 看注释吧!好懂!
// 你把汉诺塔问题想象成二叉树
// 比如当前还剩i层其实打印这个过程就是
// 1) 去打印第一部分 -> 左子树
// 2) 打印当前的动作 -> 当前节点
// 3) 去打印第二部分 -> 右子树
// 那么你只需要记录每一个任务 : 有没有加入过左子树的任务
// 就可以完成迭代对递归的替代了
public static void hanoi3(int N) { public static void hanoi3(int N) {
if (N < 1) { if (N < 1) {
return; return;
} }
// 每一个记录进栈
Stack<Record> stack = new Stack<>(); Stack<Record> stack = new Stack<>();
stack.add(new Record(false, N, "left", "right", "mid")); // 记录每一个记录有没有加入过左子树的任务
HashSet<Record> finishLeft = new HashSet<>();
// 初始的任务,认为是种子
stack.add(new Record(N, "left", "right", "mid"));
while (!stack.isEmpty()) { while (!stack.isEmpty()) {
// 弹出当前任务
Record cur = stack.pop(); Record cur = stack.pop();
if (cur.base == 1) { if (cur.level == 1) {
// 如果层数只剩1了
// 直接打印
System.out.println("Move 1 from " + cur.from + " to " + cur.to); System.out.println("Move 1 from " + cur.from + " to " + cur.to);
if (!stack.isEmpty()) {
stack.peek().finish1 = true;
}
} else { } else {
if (!cur.finish1) { // 如果不只1层
if (!finishLeft.contains(cur)) {
// 如果当前任务没有加入过左子树的任务
// 现在就要加入了!
// 把当前的任务重新压回去,因为还不到打印的时候
// 再加入左子树任务!
finishLeft.add(cur);
stack.push(cur); stack.push(cur);
stack.push(new Record(false, cur.base - 1, cur.from, cur.other, cur.to)); stack.push(new Record(cur.level - 1, cur.from, cur.other, cur.to));
} else { } else {
System.out.println("Move " + cur.base + " from " + cur.from + " to " + cur.to); // 如果当前任务加入过左子树的任务
stack.push(new Record(false, cur.base - 1, cur.other, cur.to, cur.from)); // 说明此时已经是第二次弹出了!
// 说明左子树的所有打印任务都完成了
// 当前可以打印了!
// 然后加入右子树的任务
// 当前的任务可以永远的丢弃了!
// 因为完成了左子树、打印了自己、加入了右子树
// 再也不用回到这个任务了
System.out.println("Move " + cur.level + " from " + cur.from + " to " + cur.to);
stack.push(new Record(cur.level - 1, cur.other, cur.to, cur.from));
} }
} }
} }
@ -132,8 +159,8 @@ public class Code02_Hanoi {
hanoi1(n); hanoi1(n);
System.out.println("============"); System.out.println("============");
hanoi2(n); hanoi2(n);
// System.out.println("============"); System.out.println("============");
// hanoi3(n); hanoi3(n);
} }
} }

Loading…
Cancel
Save