解析递归的河内塔算法

时间:2013-06-15 03:46:32

标签: algorithm towers-of-hanoi

我很抱歉提出这个问题,但我没有发现任何其他现有的线程有用。我不得不说我很难绕过复杂的话题,也许我只是愚蠢。我为此深表歉意。无论如何,我试图解析以下内容,但有一些不妥。

   public class tower {
  public static void move(int n, int startPole, int endPole) {
    if (n== 0){
      return;
    }
    int intermediatePole = 6 - startPole - endPole;
    move(n-1, startPole, intermediatePole);
    System.out.println("Move " +n + " from " + startPole + " to " +endPole);
    move(n-1, intermediatePole, endPole);
  }

  public static void main(String[] args) {
    move(2, 1, 3);
  }
}

我写了一些笔记来帮助自己解析代码:

move(2,1,3)
move(1,1,2)
n==0

--------going back up

n==0
move(1,1,2)
Move 1 from 1 to 2
move(2,1,3)
Move 2 from 1 to 3

move(2,1,3)
move(1,2,3)
n==0

-------going back up

n==0
move(1,2,3)
Move 1 from 2 to 3
move(2,1,3)
?????????? (step is missing)

第二次递归调用过早停止,我想知道我忽略了什么。

我发现迭代代码更容易理解,我写了一个基于迭代算法的递归算法。

2 个答案:

答案 0 :(得分:0)

我怀疑你的笔记是否正确,看起来很混乱。

当你的代码执行时,它运行如下:

  
    

移动(2,1,3)

  

转向

  
    

移动(1,1,2)

         

(输出)“将2从1移动到3”

         

移动(1,2,3)

  

,而

  
    

移动(1,1,2)

  

转向

  
    

move(0,1,3)//什么都不做

         

(输出)“将1从1移动到2”

         

move(0,3,2)//什么都不做

  

  
    

移动(1,2,3)

  

转向

  
    

move(0,2,1)//什么都不做

         

(输出)“将1从2移动到3”

         

move(0,1,3)//什么都不做

  

所以它的输出:

  
    

“将1从1移动到2”

         

“将2从1移动到3”

         

“将1从2移动到3”

  

令人费解的是输出中的n。它在move()中很重要,只是描述了在此移动中移动的元素之和(n-1,...,...) ,移动(n,...,...)和下一步移动(n-1,...,...),不仅仅是移动(n,...,...)。

答案 1 :(得分:0)

move(2,1,3)
+--move(1,1,2)
|  +--move(0,1,3)
|  |  '--(do nothing)
|  +--print "move from 1 to 2"
|  '--move(0,3,2)
|     '--(do nothing)
+--print "move from 1 to 3"
'--move(1,2,3)
   +--move(0,2,1)
   |  '--(do nothing)
   +--print "move from 2 to 3"
   '--move(0,1,3)
      '--(do nothing)

要将 n 光盘从Tower a 移动到tower b ,您需要

  1. 使用塔式 c 将顶部 n - 1个光盘移开。
  2. 将底部光盘移至塔 b
  3. 将顶部向后移动到上一张光盘的顶部,在 b 上。
  4. 步骤1和3以递归方式完成。


    /** Moves n discs from startPole to endPole */
    public static void move(int n, int startPole, int endPole) {
        if (n == 0) {
            // Base case: No disk to move. Do nothing.
            return;
        }
    
        // Calculate the pole that is not startPole and not endPole.
        // 1 + 2 + 3 = 6
        // 6 - 1 - 2 = 3
        // 6 - 1 - 3 = 2
        // 6 - 2 - 3 = 1
        int intermediatePole = 6 - startPole - endPole;
    
        // Step 1: Move n-1 discs out of the way, to the intermediate pole.
        move(n-1, startPole, intermediatePole);
    
        // Step 2: Move the bottom disc to the destination, the end pole.
        System.out.println("Move " + n + " from " + startPole + " to " + endPole);
    
        // Step 3: Move the n-1 discs back on top of the previous disc, on the end pole.
        move(n-1, intermediatePole, endPole);
    }