河内塔递归解决方案错误

时间:2015-10-28 08:34:59

标签: java recursion

教授向我们展示了河内塔问题的递归解决方案:

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]

但是这个解决方案对应于网络上的很多例子。 所以,问题是:这样的任何解决方案(我在网络上找到的)确实包含错误或者我对递归的理解是错误的吗?

1 个答案:

答案 0 :(得分:1)

有意义的是,如果你注释掉部分工作算法,它就会停止工作。

(正确)递归实施河内塔的想法是,如果你必须将n个元素从第一个塔移动到第三个塔,你首先递归地将元素n-1移动到第二个塔,而不是你将第n个元素移动到第三个塔,最后你递归地将元素n-1移动到第三个塔。如果你跳过第二次递归调用,它根本不起作用。