河内的塔楼在python中递归,了解光盘目的地的变化

时间:2014-04-25 10:35:11

标签: python recursion towers-of-hanoi

我正在努力提高我对python中河内塔的递归解法代码的理解。

此代码:

def moveTower(height,fromPole, toPole, withPole):
    if height >= 1:
        print( "    "*(3-height), "moveTower:", height, fromPole, toPole )
        moveTower(height-1,fromPole,withPole,toPole)
        moveDisk(fromPole,toPole,height)
        moveTower(height-1,withPole,toPole,fromPole)
    #print(withPole)

def moveDisk(fp,tp,height):
    print("    "*(4-height), "moving disk", "~"*(height), "from",fp,"to",tp)


moveTower(3,"A","B","C")

将打印解决拼图所需的正确动作,所以我前一段时间询问堆栈溢出,以解释它是如何做到的。我得到了这个答案

moveTower: 3 A B
     moveTower: 2 A C
         moveTower: 1 A B
             moving disk ~ from A to B
         moving disk ~~ from A to C
         moveTower: 1 B C
             moving disk ~ from B to C
     moving disk ~~~ from A to B
     moveTower: 2 C B
         moveTower: 1 C A
             moving disk ~ from C to A
         moving disk ~~ from C to B
         moveTower: 1 A B
             moving disk ~ from A to B

我唯一不了解这个解释的是,在递归中,光盘目的地(钉子a,b,c)是如何变化的?第3行 - moveTower:1 AB,是正确的,我知道光盘应该从A移动到B但我不明白我们如何从A到C(第2行)到新的目的地是B !这很难解释,如果你不明白我的意思请问,但我真的希望得到一些帮助来理解这一点!

这就是我所理解的代码看起来像3个光盘从= A,到= B,有= C我已经写了我认为递归会是什么样的(这忽略了大部分代码,我只专注于顶部

def moveTower(3,A, B, C):
    if height >= 1:

        moveTower(2,A,C,B)
            moveTower(1,A, C, B) #so this line of code should be A,B,C but why? as in recursion do we not simply repeat the code again and again? so why would it change if the code initially is ACB why does it change to ABC? 
            moveDisk(A,B,3)
            moveTower(1,C,B,A)

1 个答案:

答案 0 :(得分:1)

不要混淆程序中编写的代码和执行的代码,尤其是变量名称!

def moveTower(3, A, B, C):
    if height >= 1:

        moveTower(2,A,C,B)
            moveTower(1,A, C, B) #so this line of code should be A,B,C but why? as in recursion do we not simply repeat the code again and again? so why would it change if the code initially is ACB why does it change to ABC? 
            moveDisk(A,B,3)
            moveTower(1,C,B,A)

从具有较短变量名称的正确代码中考虑此代码段:

def moveTower(height, a, b, c):
    if height >= 1:
        moveTower(height-1, a, c, b)

如果第一个呼叫是moveTower(3, 'Peg1', 'Peg2, 'Peg3'),这意味着必须将3个磁盘(整个塔)从挂钉1移动到挂钩2,同时使用挂钩3作为临时存储。现在,在函数moveTower中,变量a获得'Peg1'b获得'Peg2'c获得'Peg3'

现在递归开始:将3个磁盘从peg 1移动到peg 2,首先将两个磁盘移动到" helper peg",然后使用第三个peg作为新助手:

moveTower(2, a, c, b) # in the first call, a=Peg1, b=Peg2, c=Peg3

这会导致另一次moveTower的调用,但这一次,我们得到:a得到'Peg1'b获得'Peg3'和{{1}获取c,因为'Peg2'c在通话中交换了。然后发生另一个递归步骤:

b

变量名称相同,但现在它们具有不同的值:moveTower(1, a, c, b) c!因此,在'Peg2'的下一个实例中,我们(与第一次调用相同):moveTower获取a'Peg1'获取b ,因为它是第二个参数,在调用'Peg2'时,第二个参数为moveTower c='Peg2'获取c来自前者'Peg3'

我希望这会有所帮助。如果你手工(使用笔和纸)进行递归并写下来,你可能也会更好地理解它,哪个变量在每一步都有哪些内容。