河内的塔:Ruby中的递归解释

时间:2013-08-21 18:02:42

标签: ruby recursion towers-of-hanoi

注意:我理解递归解决方案;但我不知道代码是如何实现的,因为我无法按照代码执行的步骤进行操作。

我很难理解河内塔的递归循环。我已经评论并尝试了各种策略,以了解程序是如何运作的,但我似乎无法掌握循环如何运作以及如何指示环。

  def move(rings, from, destination, other)
    if rings == 1
      ring = from.pop
      p "Move ring #{ring} from #{from} to #{destination}"
      destination.push ring
    else
      move(rings-1, from, other, destination)
      move(1, from, destination, other)
      move(rings-1, other, destination, from)
    end
  end

这是输出:

"Move ring 1 from a to c"
"Move ring 2 from a to b"
"Move ring 1 from c to b"
"Move ring 3 from a to c"
"Move ring 1 from b to a"
"Move ring 2 from b to c"
"Move ring 1 from a to c"

我看过各种解释,但是,我没有看到解释如何执行循环的解释。例如,我无法弄清楚为什么在环是偶数的情况下,第一步将环1从a放到b,而对于所有奇数环,它是从a到c,如上所示。

我理解解决方案背后的逻辑,为了在使用辅助挂钩时将n个环移动到目的地,需要先将n-1个环移动到辅助挂钩,然后将第n个环移动到目的地并再次重复第一个程序。但是,我不确定放置的方向是如何变化的,例如,当上面的移动方法调用似乎没有提到c到b时,我看不到块从c到b是怎么回事。

提前感谢您的时间和帮助。

另外,如果您有任何关于帮助跟踪Ruby中代码执行过程的建议,请告诉我们。我很想听听你对如何解决你不确定如何执行事件的实例的一些见解。

渴望听到你的回答:)

1 个答案:

答案 0 :(得分:6)

河内塔是Divide and Conquer algorithm的一个很好的例子。 您有一个理所当然的算法,它可以将所有元素从源移动到目标,通过将除最后一个元素之外的所有元素移动到备用区域,然后将最后一个元素从源移动到目标,从而将所有元素从备用移动到目标。

每次移动的调用都不是基本案例,而是以指数方式分成2个以上的调用,直到达到基本情况为止。你的3盘游戏的痕迹,只考虑第一部分(移动中间元素之前)是:

move(3, source, dest, spare)
move(2, source, spare, dest)
move(1, source, dest, spare) 

输出“将环1从源移动到备用”

这里的技巧是传递的参数(堆栈)对于不同的级别具有不同的角色。对于2.级别,目的地是3.级别备用。当突然从备用地移动到目的地时,源被用作备用,但功能并不关心。它只是在它击中基础情况之前进行改组。 n个光盘有2 ^ n-1个移动(基本情况命中)。

递归在返回之前完成第二级,然后3.层在移动它的中间后开始另一个2.层,用于从备用到目的地的移动。

提示:您应该在开头添加跟踪文本,例如“输入3,a,c,b”,最后添加“退出3,a,c,b”。这应该可以让你知道有多少递归和它是如何完成的。

相关问题