递归函数

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)
 
 
 

以上是关于递归函数的主要内容,如果未能解决你的问题,请参考以下文章

UE4定义递归函数

递归与内置函数

函数递归

python 递归与递归函数

python - - 函数 - - 递归函数

R语言递归函数示例(Recursive Functions):使用递归函数计算阶乘使用递归函数计算数据序列的平方和