河内之塔-python-递归
我知道这个话题有很多问题,但我没有找到答案 我找到了解决河内塔问题的代码。代码如下:河内之塔-python-递归,python,recursion,Python,Recursion,我知道这个话题有很多问题,但我没有找到答案 我找到了解决河内塔问题的代码。代码如下: def move(x, y): print(f"move disc from {x} to {y}") def solve_hanoi(n, frompoint, helper, destination): if n == 0: pass else: solve_hanoi(n-1, frompoint, destinatio
def move(x, y):
print(f"move disc from {x} to {y}")
def solve_hanoi(n, frompoint, helper, destination):
if n == 0:
pass
else:
solve_hanoi(n-1, frompoint, destination, helper)
move(frompoint, destination)
solve_hanoi(n-1, helper, frompoint, destination)
solve_hanoi(3, "A", "B", "C")
在输出“将光盘从A移到C”之前,我了解的最初几个步骤。但我不明白下一个输出是如何“从A移到B”(它是)
因为在函数移动之后,函数solve_hanoi(n-1,helper,frompoint,destination)将打开。n-1现在是0,因此函数将被传递。但是为什么n=1的元组也通过了
希望你能理解我的问题并能帮助我
亲切的问候我想我理解你的问题。我试着在实时编程站点上运行你的代码,但是没有传递n=1的函数 当n=1的帧被“关闭”时,执行函数调用并调用solve_hanoi(0,frompoint,destination,helper)(显然是传递的),然后执行move(),最后调用solve_hanoi(0,helper,frompoint,destination),该函数也被传递
我不明白问题是什么,因为一切都在正确执行事实上,调用
move
之后的第二次调用也会得到n=0
,并且会返回而不做任何操作。但随后递归回溯到调用者,调用者也在等待其else
块中第一个递归调用的返回。但是在这个上下文中,n
是2
它可能有助于描述递归堆栈,即等待递归调用返回的函数执行列表:
solve_hanoi(n=3, frompoint="A", helper="B", destination="C")
solve_hanoi(n=2, frompoint="A", helper="C", destination="B")
solve_hanoi(n=1, frompoint="A", helper="B", destination="C")
solve_hanoi(n=0, frompoint="A", helper="C", destination="B")
pass
return
move(x="A", y="C") # frompoint, destination
print("move disc from A to C")
return
solve_hanoi(n=0, frompoint="B", helper="A", destination="C")
pass
return
return
move(x="A", y="B") # note how this move is not at the same depth as the previous one
print("move disc from A to B")
return
solve_hanoi(n=1, frompoint="C", helper="A", destination="B")
# ... etc
请注意堆栈框架。“从B到A”的输出来自前面的函数调用;“从A到C”不会再打电话了。查看顺序树遍历可能有助于您理解。将对solv_hanoi(n,…)的调用概念化为“利用备用主轴将大小为n的堆从源移动到目标”。这是通过将大小为n-1的堆移动到备用磁盘,露出底部磁盘,您可以将其移动到目的地,然后将大小为n-1的堆从备用堆移动到目的地。递归调用会重新定位堆,而对
移动
的调用会移动单个磁盘。如前所述,基本情况是移动大小为0的一堆,这没有任何作用。非常感谢!我自己画了一个顺序树,在你的帮助下,我能够重建代码。但这是非常棘手的,它只是n=3。我该怎么做呢?如果我有顺序树,我该怎么做递归代码呢?没有简单的方法可以将一般的树问题转化为递归代码。您需要确定“基本情况”是什么(叶的特征),在递归步骤之前必须发生什么,以及在递归步骤之后发生什么。如果树不是必需的二进制文件,那么您可能会在“children”上有一个循环,并对每个children进行递归调用。变化是数不清的。