如何用河内塔调用递归

时间:2019-01-17 12:08:15

标签: java recursion towers-of-hanoi

我正试图解决河内塔问题;我写了这段代码:

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

   public static void move(int disks, int from, int to) {
      if (disks > 0) {
         int other = 6 - from - to; // sum of index 1+2+3=6
         System.out.println("Move disk from peg " + from + " to " + to);
         move(disks - 1, from, other);
         move(disks - 1, other, to);
         }
   }
}

但是结果是错误的。我书中的解决方案是

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

   public static void move(int disks, int from, int to) {
      if (disks > 0) {
         int other = 6 - from - to; // sum of index 1+2+3=6
         move(disks - 1, from, other);
         System.out.println("Move disk from peg " + from + " to " + to);
         move(disks - 1, other, to);
         }
   }
}

这是为什么?我无法理解这些表达式的顺序:

  • 首先运行System.out.println()
  • 然后运行move(disks - 1, from, other)
  • 现在它再次运行System.out.println()还是运行move(disks - 1, other, to)

以及何时重新启动该阻止代码?谢谢。

3 个答案:

答案 0 :(得分:2)

河内塔的运作方式-:

  1. 首先,您必须使用3将n-1个磁盘从第一个磁盘移到第二个磁盘栓。
  2. 将最后的第n个磁盘移动到第3个钉上。
  3. 使用1st将n-1磁盘从第二个钉移到第三个钉上。

图书解决方案正确。您的解决方案是错误的,因为您已移动了最后一个磁盘,这违反了河内塔的规则。我希望你能明白。

经过一些修改后的代码,对于任何惯用的n都可以使用,更加优雅和易于理解。 (由于n的指数复杂性,所以尽量不使用n)

public class TowersOfHanoi {
   public static void main(String[] args) {
      int first = 1, second = 2, third = 3;
      int disk = 5; // or take user input
      move(disk, first, third);
   }

   public static void move(int disks, int first, int second, int third) {
      if (disks > 0) {
              move(disks - 1, first, third, second); // source = first, dest = second
              System.out.println("Move disk from peg " + first+ " to " + third);
              move(disks - 1, second, first, third);  // source = second, dest = third
         }
   }
}

答案 1 :(得分:1)

正确解决方案的想法是:

  1. 首先,您必须递归地将前n-1个光盘从钉子“从”移动到钉子“其他”。
  2. 然后,您可以将底部光盘从钉子“从”移动到钉子“至”-这就是println语句。
  3. 然后,您必须递归地将n-1个光盘(在第1步中移动过)从钉子“ other”移动到钉子“ to”。

另一方面,在不正确的解决方案中,您要执行的操作是先移动底部光盘,然后再移动堆叠在其上方的所有光盘,这是无效的举动。

答案 2 :(得分:0)

因此,我们有n个磁盘和3个钉,我们希望将放置在第一个钉(源钉)中的磁盘移动到第三个钉(目标钉)中;在这种情况下,递归的概念是:

  1. 将所有磁盘从1递归移动到最大磁盘(称为n-1)上方的n上,从第一个钉移到第二个(备用钉),因为我们要为最大的磁盘腾出空间,然后将其放入第三个挂钩中。这是第一句子move(disks - 1, from, other);

  2. 将所有磁盘移到最大磁盘上方后,我们将其移至第三钉:作为Wikipedia says,这是简单的步骤,其 second 句子
    System.out.println("Move disk from peg " + from + " to " + to);

  3. 最后,将所有n-1磁盘从第二个钉移到第三个钉上,以便在第三个钉上重建塔楼,并重建其最后一个句子move(disks - 1, other, to);

此算法适用于偶数和奇数n磁盘,因为它具有g 能量求解过程,显然,步骤会根据磁盘的初始数量而变化。