教授向我们展示了河内塔问题的递归解决方案:
public class Hanoi {
static Stack<Integer> from;
static Stack<Integer> temp;
static Stack<Integer> to;
public static void print() {
System.out.println("------------------------");
System.out.println(" FIRST " + from.toString());
System.out.println("SECOND " + temp.toString());
System.out.println(" THIRD " + to.toString());
}
public static void move(Stack<Integer> from, Stack<Integer> to) {
to.push(from.pop());
print();
}
public static void invokeHanoiLogic(Stack<Integer> first, Stack<Integer> second, Stack<Integer> third, int quantity) {
if(quantity > 0) {
invokeHanoiLogic(first, third, second, quantity - 1);
move(first, third);
invokeHanoiLogic(second, first, third, quantity - 1);
}
}
public static void main(String[] args) {
from = new Stack<>();
temp = new Stack<>();
to = new Stack<>();
from.push(3);
from.push(2);
from.push(1);
invokeHanoiLogic(from, temp, to, from.size());
}
}
但是如果我们评论第三个字符串// invokeHanoiLogic(第二个,第一个,第三个,数量 - 1);检查第一个递归深度结果:
if(quantity > 0) {
invokeHanoiLogic(first, third, second, quantity - 1);
move(first, third);
//invokeHanoiLogic(second, first, third, quantity - 1);
}
我在控制台日志中发现错误:
------------------------
FIRST [5, 4, 3, 2]
SECOND []
THIRD [1]
------------------------
FIRST [5, 4, 3]
SECOND [2]
THIRD [1]
------------------------
FIRST [5, 4]
SECOND [2]
THIRD [1, 3]
------------------------
FIRST [5]
SECOND [2, 4]
THIRD [1, 3]
------------------------
FIRST []
SECOND [2, 4]
THIRD [1, 3, 5]
但是这个解决方案对应于网络上的很多例子。 所以,问题是:这样的任何解决方案(我在网络上找到的)确实包含错误或者我对递归的理解是错误的吗?
答案 0 :(得分:1)
有意义的是,如果你注释掉部分工作算法,它就会停止工作。
(正确)递归实施河内塔的想法是,如果你必须将n个元素从第一个塔移动到第三个塔,你首先递归地将元素n-1移动到第二个塔,而不是你将第n个元素移动到第三个塔,最后你递归地将元素n-1移动到第三个塔。如果你跳过第二次递归调用,它根本不起作用。