【问题标题】:Crockford's hanoi function (from "The Good Parts") [duplicate]Crockford 的河内函数(来自“The Good Parts”)[重复]
【发布时间】:2017-10-18 20:34:35
【问题描述】:

目前我正在阅读 Douglas Crockford 的书,河内塔楼功能有点超出我的想象。即使将内容记录到控制台,我也无法真正理解发生了什么。这是我添加的功能:

var hanoi = function (disc, src, aux, dst) {
  console.log(disc);
  console.log(src, dst);    
  if (disc > 0) {
    hanoi(disc - 1, src, dst, aux);
    console.log('Move disc ' + disc + ' from ' + src + ' to ' + dst);
    hanoi(disc - 1, aux, src, dst);
  }
}

hanoi(3, 'Src', 'Aux', 'Dst');

这会导致以下结果:

3
源地址
2
源辅助
1
源地址
0
源辅助
将磁盘 1 从 Src 移动到 Dst
0
辅助 Dst
将光盘 2 从 Src 移动到 Aux
1
Dst 辅助
0
Dst Src
将光盘 1 从 Dst 移动到 Aux
0
源辅助
将磁盘 3 从 Src 移动到 Dst
2
辅助 Dst
1
辅助源
0
辅助 Dst
将磁盘 1 从 Aux 移动到 Src
0
Dst Src
将光盘 2 从 Aux 移动到 Dst
1
源地址
0
源辅助
将磁盘 1 从 Src 移动到 Dst
0
辅助目的地

而且我很早就迷路了。结果第6行,怎么从Src Aux回到Src Dst?

当函数只使用“disc - 1”调用自身时,磁盘的数量一旦达到 0 怎么能再次增加?

【问题讨论】:

  • 如果你读过 Crockford 的学习 JavaScript 的书,你可以跳过这部分,因为它与 JavaScript 语言本身无关,而且算法也不是微不足道的。当然,如果你还有兴趣,可以查看维基百科的解释:en.wikipedia.org/wiki/Tower_of_Hanoi
  • 理论上我理解这个问题和解决方案,但我不明白这个功能是如何工作的(还)。所以对于我作为 JS 程序员的发展,理解这一点并不是无关紧要的,即使我知道你的意思。非常感谢您的意见。

标签: javascript recursion towers-of-hanoi


【解决方案1】:

之所以会产生混淆,是因为输出的文本表示并不是理解递归的最佳方式。光盘的数量并没有“增加”,而是在 hanoi(0) 完成后继续运行的 hanoi(1)

我在JSBin 创建了一个修改后的示例,它以(有点)更漂亮的方式打印输出,带有空格。只有“移动”实际上做任何事情,其余的行只是递归调用以解决较小的子问题,以便以后解决整个问题。

您可能还想看看这个Java applet,它以图形方式显示了算法的工作原理 - 这可能更容易理解。

【讨论】:

  • 非常感谢!我认为这会有所帮助:)
【解决方案2】:

河内塔是递归如何简化给定问题的一个很好的例子。想法如下:您必须将 N 个磁盘从源堆栈移动到目标堆栈,一次一个磁盘,并且永远不能将较大的磁盘放在较小的磁盘上。您可以使用辅助堆栈。假设 N = 10。你不知道如何解决它。但是你可以让问题更简单(你希望):

move 9 disks to the auxiliary stack,  
move the remaining (and largest!) disk to the destination stack, and  
move the 9 disks from the auxiliary stack to the destination stack  

同样,您不知道如何移动 9 个磁盘堆栈,但这也没有问题:

move 8 disks from the auxiliary stack to the source stack,  
move the remaining disk to the destination stack (there are 2 disks now), and  
move the 8 disks from the source stack to the destination stack  

重复此操作,直到您必须移动的堆栈只有 1 个磁盘大。

关于再次上升的磁盘数:你递归调用函数对N-1个磁盘,在函数中分配给N。这个N只存在到函数结束,并返回到上一层。然后你再次得到 N 的旧值。

【讨论】:

    猜你喜欢
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 2011-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多