微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JavaScript – 河内塔的递归算法如何运作?

这是我从一本书中解释递归的代码.问题是我不明白程序采取的步骤:
var hanoi = function(disc,src,aux,dst) {
    if (disc > 0) {
        hanoi(disc - 1,dst,aux);
        document.write("Move disc " + disc + " from " + src + " to " + dst + "<br />");
        hanoi(disc - 1,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作为“辅助”栓:

>将x-1光盘从钉A移动到钉B,使用钉C作为辅助钉.
>将第x个光盘从钉A移动到钉C(不需要辅助,因为您只能移动一张光盘).
>使用钉A作为辅助钉,将x-1碟从钉板B移动到钉C上.

请注意,为了移动x光盘,您必须移动x-1张光盘.您可以使用相同的功能来移动这些x-1光盘,并且只需切换哪个连接头就是源,目标和辅助连接.这就是河内的塔楼这样一个常见的递归的例子,这就是你需要在问题中看到的模式,以便为你的递归工作.它不需要“移动x-1光盘”,当然可以这样的“列出这个子文件夹”.树(就像具有子文件夹等的目录)是递归闪耀的另一个地方.与其他作业一样,为了在一个项目上完成这项工作,您可能需要对子项目做同样的工作.

现在,为了有用的递归,你需要一个“基本情况” – 递归将停止的条件.如果不这样做,代码将永远运行(或至少直到内存不足或溢出调用堆栈).这种情况发生在x == 0(因为移动0光盘意味着你什么都不做,因为在功能的周围).它也可能是当x == 1,因为你不必递归,但额外的,如果在每个河内调用之前会增加一点噪音(并且递归解决方案的主要好处是它的简单性).无论如何,当x == 0时,函数返回而不做任何事情.调用它的函数(它有x == 1)现在可以继续执行其操作 – 在这种情况下,说“将光盘1从src移动到dest”,然后再次使用args切换来调用hanoi函数.

流程有点像这样:

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

    print "Move 2 from src to aux"

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

  print "move 3 from src to dest"

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

    print "Move 2 from aux to dest"

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐