Python 递归原理(斐波那契数列为例)的疑问

wu5261092 2018-06-25 07:03:24
各位好!
最近在学习递归的时候碰到了一些运行原理上的疑问,特来此请教大家

代码如下
def fastFib(n,memo):
global numCalls
numCalls += 1
print('fib called with',n)
if not n in memo:
memo[n] = fastFib(n-1,memo) + fastFib(n-2,memo)
return memo[n]

def fastFib1(n,memo):
global numCalls
numCalls = 0
res = fastFib(n,memo)
print('fastFib of',n,'=',res,', numCalls =',numCalls)

运行结果图如下


现有一个问题,描述如下表所示


为啥最后还要再调用一下n=1,2,3的情况呢?我推测是
Fb(5,memo)=Fb(4,memo)+Fb(3,memo)
Fb(4,memo)=Fb(3,memo)+Fb(2,memo)
Fb(3,memo)=Fb(2,memo)+Fb(1,memo)

但Fb(1,memo)不是已经计算过一次了吗?为啥还要再计算一次?

求助各位详细描述一下Python中递归的原理

感谢!
...全文
403 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
wu5261092 2018-07-02
  • 打赏
  • 举报
回复
感谢你的及时回复!为了弄清楚这个问题,我这些天一直在查找相关的资料,现在弄懂啦 谢谢你!

引用 2 楼 hbu_pig 的回复:
你可以通过调换n-1和n-2的顺序,如:f(n)=f(n-2)+f(n-1)来更好的理解栈结构

Fib(5)-->return Fib(4)+Fib(3),这时内存将打开三个抽屉,Fib(5)是一个大抽屉,里头包含了Fib(4),Fib(3)两个小抽屉;

然后根据顺序,先运行Fib(4),return Fib(3)+Fib(2),在Fib(4)这个抽屉里又开了两个小抽屉,Fib(3)和Fib(2);

就这么一直运行,直到Fib(2)开了两个小抽屉,一个Fib(1),一个Fib(0),这两个小抽屉打开,发现真正的值,所以可以立即关上。

此时Fib(2)的值也知道了,也可以关上这个抽屉。与此同时,记录下Fib(2)的值,下次就不用再打开两个小抽屉看了。

但Fib(3)=Fib(2)+Fib(1);还有一个Fib(1)的屉子需要关上,因此打开-->发现值后-->关上。与此同时,记录下Fib(3)的值,下次就不用再打开里头的小抽屉看了。

Fib(4)= Fib(3)+Fib(2);Fib(3)的屉子关上了,里头还有一个Fib(2)的, 但我们已经记录好Fib(2)的值了,因此只需打开Fib(2)的抽屉,不必打开内部的小抽屉,直接可以知道值。

Fib(5)= Fib(4)+Fib(3);Fib(4)的屉子关上了,里头还有一个Fib(3)的, 但我们已经记录好Fib(3)的值了,因此只需打开Fib(3)的抽屉,不必打开内部的小抽屉,直接可以知道值。

打开的屉子数就是占用的内存数




换过来以后也理解了

欢乐的小猪 2018-06-25
  • 打赏
  • 举报
回复
你可以通过调换n-1和n-2的顺序,如:f(n)=f(n-2)+f(n-1)来更好的理解栈结构
欢乐的小猪 2018-06-25
  • 打赏
  • 举报
回复
递归是依赖计算机的一种数据结构——栈来实现的。它最重要的特点就是先入后出,后入先出。
你调用f5,需要将f4和f3压栈,然后f4出栈,把f3和f2压栈,。。。。。
内容概要:本文系统介绍了递归算法的核心概念、工作原理、必要条件、经典实例、优缺点及优化策略。递归算法通过函数调用自身,将复杂问题分解为同构的子问题进行求解,其关键在于递归基例和递推关系的设计。文章以阶乘和斐波那契数列为典型案例,展示了递归的执行流程,并深入分析了其在代码简洁性与逻辑清晰方面的优势,以及栈溢出、重复计算和调试困难等缺陷。针对这些问题,提出了记忆化递归、尾递归优化和递归转迭代三种主要优化方法,提升算法效率与稳定性。最后对递归在现代计算领域的应用前景进行了展望。; 适合人群:具备基本编程基础,正在学习算法设计与分析的初学者及中级开发者,尤其是高校计算机专业学生或从事软件开发1-3年的技术人员。; 使用场景及目标:①理解递归的基本原理及其在阶乘、斐波那契数列、树遍历等问题中的应用;②掌握递归算法的常见性能问题与优化技巧,如记忆化、尾递归和迭代转换;③为后续学习分治算法、动态规划、深度优先搜索等高级算法打下坚实基础。; 阅读建议:建议结合代码示例动手实践,重点关注递归的调用栈变化过程和优化前后的时间复杂度对比,通过调试工具观察递推与回溯的执行顺序,加深对递归机制的理解。

37,743

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • WuKongSecurity@BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧