递归函数
Posted pythonerLau
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了递归函数相关的知识,希望对你有一定的参考价值。
变量名解析原则LEGB
local 本地作用域,局部作用域的命名空间,函数调用时创建,调用结束消亡
Enclosing,python2.2时引入嵌套函数,实现了闭包。就是函数嵌套的外部函数的命名空间
Global,全局作用域,即一个模块的命名空间,模块被import时创建,解释器退出消亡
Build-in ,内置模块的命名空间生命周期从python解释器启动时创建到解释器退出时消亡。例如print(open),print和open都是内置的变量
所以名词查找顺序 就是L-->E-->-->G-->B
函数递归:
例子(1,1):
def foo1(b,b=3):
print(‘foo1 called‘,b,b1)
def foo2(c):
foo3(c)
print(‘foo2 called,c)
def foo3(d):
print(‘foo3 called‘,d)
def main():
print(‘main called‘)
foo1(100,101)
foo2(200)
print(‘main ending‘)
main()
递归示例(1,1)分析:
全局帧中生成foo1,foo2,foo3main函数对象
1.main函数调用
2.main中查找 内建函数 print压栈,将常量字符串压栈,调用函数,弹出栈顶
3.mani函数中全局查找foo1压栈,将常量100,101压栈,调用函数foo1,创建 栈帧,->print函数压栈,字符串常量压栈,调用函数,弹出栈顶
4.main函数中全局查找foo2压栈,将常量200压栈,调用函数foo2;创建栈帧,foo3函数压栈,变量c引用压栈,调用函数foo3 创建栈帧,foo3完成print函数调用后返回foo2恢复调用,执行print后,返回值。main中foo2调用结束弹出栈顶,main函数继续向后执行print函数调用,弹出栈顶。main函数返回
自我理解:
main函数调用->调用print函数返回字符串->查找foo1函数并传参并调用函数print返回字符串->查找foo2函数并传参调用->foo2函数中含有foo3函数调用->foo3函数调用print函数并返回字符串-> 最后main函数调用print函数返回
利用pychrm 断点判断函数嵌套使用是否正常
递归Recursion:
函数直接或者间接调用自身就是递归; (自己调用自己)
递归要有边界条件,递归前进段,递归返回段
递归一定要边界条件
当条件不满足时,递归前进
当条件满足的时候,递归返回
利用递归实现斐波那契数列:
for循环实现
(1,2)
pre=0
cur=1 第一个数
print(pre,cur,end=‘ ‘)
n=4
for i in range(n-1):
pre,cur=cur,pre+cur
print(cur,end=‘ ‘)
递归调用自实现
斐波那契数列的数学公式:
(1,2,1)
F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)
def fib(n):
return 1 if n<2 else fib(n-1)+fib(n-2)
for i in range(5):
print(fib(i),end=‘ ‘)
fib(2)是边界,每一个递归函数都必须有一个边界
利用边界来计算,但是效率很低,公式那里递归了很多次
总结:
递归要求:
一定要有退出条件,没有递归条件,就无限循环
递归深度不宜过深,否则会超出限制
查询当前最大递归深度 sys.getrecusionlimit()
递归的性能:
循环稍微复杂,不是死循环,就能多次迭代出结果
递归 有深度限制,函数反复压栈,内存溢出快
递归斐波那契数列的性能改进:
(1,3)
def fib(n,pre=0,cur=1):
pre,cur=cur,pre+cur
print(cur,end=‘ ‘)
if n==2:
return
fib(n-1,pre,cur)
fib(n)
代码(1,3)分析:
上述的fib函数和循环的思想类似
参数n是边界条件,用n来计数
上一次的计算结果直接作为函数的实参
效率高,和循环性能相近,但是递归深度有限
间接递归:
def foo1():
foo2()
def foo2():
foo1():
foo1:
间接递归,是通过别的函数调用函数自身;
得注意循环递归,代码越复杂,越容易发生,所以代码得规范使用,避免出错
递归总结:
递归是一种自然表达,符合逻辑
递归相对运行效率低,每一次都调用函数都要开辟栈帧
递归有深度限制,栈内存容易溢出
大部分递归都可以用循环实现
能不要则不用递归
递归习题:
算阶乘
def foo(n,m=1):
m*=n
if n==1:
return m
return foo(n-1,m)
foo(5)
将1234倒叙打印
p=1234
def foo(n,m=[]):
m.append(str(p)[n-1])
if n==1:
return m
return foo(n-1)
foo(len(str(p)))
猴子吃桃:
def peach(day=9,sum=1):
sum=(sum+1)*2
day-=1
if day==0:
return sum
return peach(day,sum)
以上是关于递归函数的主要内容,如果未能解决你的问题,请参考以下文章