鱼C论坛

 找回密码
 立即注册
查看: 1456|回复: 2

递归问题

[复制链接]
发表于 2023-10-7 13:06:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
def moveDisk(fp, tp):
    print("moving disk from %d to %d\n" % (fp, tp))
def moveTower(height, fromPole, toPole, withPole):
    if height >= 1:
        moveTower(height-1, fromPole, withPole, toPole)
        moveDisk(fromPole, toPole)
        moveTower(height-1, withPole, toPole, fromPole)
moveTower(3,1,3,2)

在执行完moveTower(3,1,3,2)后,会执行moveTower(2,1,3,2),然后再执行moveTower(1,2,3,2),不是会无限循环吗,moveDisk(fromPole, toPole)
       moveTower(height-1, withPole, toPole, fromPole)代码就执行不了,但事实上时可以执行的,这是为什么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-10-7 13:07:23 | 显示全部楼层
在递归函数中,当height>=1时,会不断地执行moveTower函数,直到height=1时,执行moveDisk函数,然后再继续执行moveTower函数。在执行moveTower(1, 2, 3, 2)时,由于height=1,所以会直接执行moveDisk(2, 3)函数,然后再返回到上一层递归函数moveTower(2, 1, 3, 2)中,执行moveTower(2, 1, 3, 2)中的moveTower(1, 1, 2, 3)函数,由于height=1,所以会直接执行moveDisk(1, 2)函数,然后再返回到上一层递归函数moveTower(3, 1, 3, 2)中,执行moveTower(3, 1, 3, 2)中的moveTower(2, 2, 3, 1)函数,由于height=2,所以会执行moveTower(2, 2, 3, 1)中的moveTower(1, 2, 3, 1)函数,由于height=1,所以会直接执行moveDisk(2, 3)函数,然后再返回到上一层递归函数moveTower(2, 2, 3, 1)中,执行moveDisk(1, 2)函数,最后再返回到moveTower(3, 1, 3, 2)函数中,执行moveTower(3, 1, 3, 2)中的moveTower(2, 1, 3, 2)函数,由于height=1,所以会直接执行moveDisk(2, 3)函数,然后再返回到上一层递归函数moveTower(3, 1, 3, 2)中,执行moveTower(3, 1, 3, 2)中的moveTower(1, 2, 3, 2)函数,由于height=1,所以会直接执行moveDisk(1, 2)函数,最终完成整个递归过程。因此,不会出现无限循环的情况。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-7 13:08:04 | 显示全部楼层
您的理解有一点混淆。在递归调用时,每次递归都会传入新的参数值,并且在特定条件下停止递归,因此不存在无限循环的情况。

让我们来详细解释一下递归的执行过程:

1. 首先,调用 moveTower(3, 1, 3, 2)
2. 进入 moveTower 函数,传入参数 (3, 1, 3, 2)
3. 因为 height >= 1,所以进入递归。
4. 首先调用 moveTower(2, 1, 2, 3)。注意:此处辅助柱和目标柱交换了位置,是因为在本次递归中,辅助柱变成了目标柱,目标柱变成了辅助柱。
5. 进入 moveTower 函数,传入参数 (2, 1, 2, 3)
6. 再次进行递归调用,调用 moveTower(1, 1, 3, 2)
7. 进入 moveTower 函数,传入参数 (1, 1, 3, 2)
8. 因为 height >= 1,所以进行递归调用。
9. 调用 moveTower(0, 1, 2, 3)。注意:在这里,height-1 的值为 0,所以不会继续递归调用。
10. 返回到上一层递归调用 moveTower(1, 1, 3, 2)
11. 调用 moveDisk(1, 3),输出移动盘子的操作。
12. 再次进行递归调用 moveTower(0, 2, 3, 1)。同样,height-1 的值为 0,不会递归调用。
13. 返回到上一层递归调用 moveTower(2, 1, 2, 3)
14. 调用 moveDisk(1, 2),输出移动盘子的操作。
15. 再次进行递归调用 moveTower(1, 3, 2, 1)
16. 进入 moveTower 函数,传入参数 (1, 3, 2, 1)
17. 同样进行递归调用 moveTower(0, 3, 1, 2),并返回。
18. 调用 moveDisk(3, 2),输出移动盘子的操作。
19. 再次进行递归调用 moveTower(0, 1, 2, 3),并返回。
20. 返回到上一层递归调用 moveTower(3, 1, 3, 2)
21. 调用 moveDisk(1, 3),输出移动盘子的操作。
22. 再次进行递归调用 moveTower(2, 2, 3, 1)
23. 进入 moveTower 函数,传入参数 (2, 2, 3, 1)
24. 同样进行递归调用 moveTower(1, 2, 1, 3),并返回。
25. 调用 moveDisk(2, 3),输出移动盘子的操作。
26. 再次进行递归调用 moveTower(1, 1, 3, 2)
27. 进入 moveTower 函数,传入参数 (1, 1, 3, 2)
28. 同样进行递归调用 moveTower(0, 1, 2, 3),并返回。
29. 调用 moveDisk(1, 2),输出移动盘子的操作。
30. 返回到上一层递归调用 moveTower(2, 2, 3, 1)
31. 调用 moveDisk(3, 1),输出移动盘子的操作。
32. 再次进行递归调用 moveTower(1, 3, 2, 1)
33. 进入 moveTower 函数,传入参数 (1, 3, 2, 1)
34. 同样进行递归调用 moveTower(0, 3, 1, 2),并返回。
35. 调用 moveDisk(3, 2),输出移动盘子的操作。
36. 返回到上一层递归调用 moveTower(2, 2, 3, 1)
37. 再次进行递归调用 moveTower(1, 2, 1, 3),并返回。
38. 调用 moveDisk(2, 3),输出移动盘子的操作。
39. 返回到上一层递归调用 moveTower(3, 1, 3, 2)
40. 返回到主程序。

所以,通过以上的递归过程,每个递归调用都会返回到上一层,并依次执行后续的代码。不存在无限循环的问题。

希望这样的解释能够清楚地回答您的疑问。如果还有其他问题,请随时提出。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-24 08:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表