javascript - 递归算法如何适用于汉诺塔?

标签 javascript recursion towers-of-hanoi

这是我解释递归的书中的代码。问题是我不明白程序采取的步骤:

var hanoi = function(disc,src,aux,dst) {
    if (disc > 0) {
        hanoi(disc - 1,src,dst,aux);
        document.write("Move disc " + disc + " from " + src + " to " + dst + "<br />");
        hanoi(disc - 1,aux,src,dst);
    }
};

hanoi(3,"src","aux","dst");

输出是这样写的:

Move disc 1 from src to dst
Move disc 2 from src to aux
Move disc 1 from dst to aux
Move disc 3 from src to dst
Move disc 1 from aux to src
Move disc 2 from aux to dst
Move disc 1 from src to dst

有人可以一步一步分解吗?这对我很有帮助。

最佳答案

可能是汉诺塔最简单的解决方案是这样的:

x 个圆盘从桩 A 移动到桩 C,使用桩 B 作为“辅助”桩:

  1. x-1 个圆盘从桩 A 移到桩 B,使用桩 C 作为辅助桩。
  2. 将第 x 个圆盘从桩 A 移到桩 C(不需要辅助桩,因为您只移动一张圆盘)。
  3. x-1 圆盘从桩 B 移到桩 C,使用桩 A 作为辅助桩。

请注意,要移动 x 个圆盘,您必须移动 x-1 个圆盘。您可以只使用相同的功能来移动那些 x-1 圆盘,并且只需切换哪些钉是源钉、目标钉和辅助钉。这就是使汉诺塔成为递归的常见例子的原因,这也是您需要在问题中看到的那种模式,以便使递归为您工作。它不一定是“移动 x-1 光盘”,当然......它可以是“列出这个子文件夹”之类的东西。树(如带有子文件夹等的目录)是递归发挥作用的另一个地方。与其他工作一样,为了在一个项目上完成工作,您可能需要在子项目上做同样的工作。

现在,为了实现有用的递归,您需要一个“基本情况”——递归停止的条件。如果不这样做,代码将永远运行(或者至少直到它用完内存或溢出调用堆栈)。这里的基本情况发生在 x == 0 时(因为移动 0 个圆盘意味着你什么都不做,因为 if 围绕着函数的核心)。也可能是当 x == 1 时,因为那时您不必递归,但每次 hanoi 调用之前的额外 if 会添加一点噪音(递归解决方案的主要好处是它的简单性)。无论如何,当 x == 0 时,函数不做任何事情就返回。调用它的函数(它有 x == 1)现在开始继续做它的事情——在这种情况下,说“将光盘 1 从 src 移动到目标”,然后调用 hanoi 参数切换后再次运行。

流程有点像这样:

hanoi(3, src, aux, dest)
  hanoi(2, src, dest, aux)
    hanoi(1, src, aux, dest)
      hanoi(0, src, dest, aux)        // no op
      print "Move 1 from src to dest"
      hanoi(0, aux, src, dest)        // no op

    print "Move 2 from src to aux"

    hanoi(1, dest, src, aux)
      hanoi(0, dest, aux, src)        // no op
      print "move 1 from dest to aux"
      hanoi(0, src, dest, aux)        // no op

  print "move 3 from src to dest"

  hanoi(2, aux, src, dest)
    hanoi(1, aux, dest, src)
      hanoi(0, aux, src, dest)        // no op
      print "Move 1 from aux to src"
      hanoi(0, dest, aux, src)        // no op

    print "Move 2 from aux to dest"

    hanoi(1, src, aux, dest)
      hanoi(0, src, dest, aux)        // no op
      print "move 1 from src to dest"
      hanoi(0, aux, src, dest)        // no op

关于javascript - 递归算法如何适用于汉诺塔?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6947653/

相关文章:

javascript - 在不可滚动的 Div 内捕获鼠标滚轮滚动

javascript - 一个javascript递归问题

python - 为什么这个输出每次都返回不同的值?

javascript - 关于更改递归函数

C++ - 不理解递归函数的流程

java - 河内 java 塔

javascript - bootstrap 4 行后面的下拉剪裁

javascript - 在 Bootstrap 下拉列表中自动选择

Javascript 或 JQuery 思维导图插件