Python中的递归详解

2024-06-04 2727阅读

文章目录

  • 1.递归函数
  • 2.递归流程图
  • 3.递归总结
  • 4.递归注意事项
  • 5.内存栈区堆区(了解内容)
  • 6.递归案例
    • 1.使用递归实现任意数n的阶乘
      • 普通实现
      • 递归实现
      • 2. 使用尾递归来实现任意数的阶乘
        • (1) 优化代码1
        • (2)优化代码2 [把尾递归需要的参数值隐藏起来,避免篡改.]
        • (3)优化代码3(扩展)
        • 3.使用递归来完成斐波那契数列

          1.递归函数

          工作中,我们可能经常会遇到递归函数的使用,今天我们就来深入讲讲什么是递归。

          递归函数 : 在函数内部,可以调用其他函数。如果一个函数在内部自己调用自己,这个函数就是递归函数。必须由出口

          递 : 去

          归 : 回

          一去一回叫做递归

          def digui(n):
              print(n,"")
              if n > 0:
                  digui(n-1)
              print(n,"")
          digui(5)
          

          #此递归函数开辟了6层空间。去的过程

          n = 5 print(5,"")  if 5 > 0:   digui(5-1) =>  digui(4) 代码阻塞在第12行,下面的代码不再执行
          n = 4 print(4,"")  if 4 > 0:   digui(4-1) =>  digui(3) 代码阻塞在第12行
          n = 3 print(3,"")  if 3 > 0:   digui(3-1) =>  digui(2) 代码阻塞在第12行
          n = 2 print(2,"")  if 2 > 0:   digui(2-1) =>  digui(1) 代码阻塞在第12行
          n = 1 print(1,"")  if 1 > 0:   digui(1-1) =>  digui(0) 代码阻塞在第12行
          n = 0 print(0,"")  if 0 > 0: 不成立 print(0,"") 到此最后一层函数空间彻底执行完毕   这是在一个空间里面打印的
          # 回的过程,从阻塞的地方代码往下走
          回到上一层函数空间  n = 1 代码在第12行的位置,继续往下执行  print(1,"")
          回到上一层函数空间  n = 2 代码在第12行的位置,继续往下执行  print(2,"")
          回到上一层函数空间  n = 3 代码在第12行的位置,继续往下执行  print(3,"")
          回到上一层函数空间  n = 4 代码在第12行的位置,继续往下执行  print(4,"")
          回到上一层函数空间  n = 5 代码在第12行的位置,继续往下执行  print(5,"")
          

          到此递归函数执行结束…

          打印 543210012345

          调用函数就得开辟空间,每次开辟的栈帧空间,代码必须全部执行完毕之后才释放空间,再回到上一个栈帧执行没结束的代码

          Python中的递归详解 第1张

          2.递归流程图

          Python中的递归详解 第2张

          每次调用函数时,都要单独在内存当中开辟空间,叫做栈帧空间,以运行函数中的代码

          3.递归总结

          (1)递归实际上是不停的开辟栈帧空间和释放栈帧空间的过程,开辟就是去的过程,释放就是回的过程
          (2)递归什么时候触发归的过程:
              1.当最后一层栈帧空间执行结束的时候,触发归的过程.
              2.当遇到return返回值的时候终止当前函数,触发归的过程.
          (3)递归不能无限的去开辟空间,可能造成内存溢出,蓝屏***机的情况, 所以一定要给予跳出的条件(如果递归的层数太大,不推荐使用)
          (4)开辟的一个个栈帧空间,数据是彼此独立不共享的.
          

          递归不能不限开辟空间

          官方说法最大默认是1000层. 但实际要看具体设备硬件性能

          Python中的递归详解 第3张

          def deepfunc():

          deepfunc()

          deepfunc()

          可以通过sys.setrecursionlimit()进行设置,但是一般默认不会超过3925-3929这个范围。

          我这台电脑最大递归深度996层

          Python中的递归详解 第4张

          4.递归注意事项

          函数调用的过程就是开辟栈帧和释放栈帧的过程,调用时开辟栈帧空间,结束时释放
          (言外之意不结束这层栈帧不释放)
          递归每次调用都会开辟一个栈帧,如果递归的层数过多,不建议使用,容易内存溢出
          每次开辟的栈帧空间,代码必须全部执行完毕之后才释放空间,在回到上一个栈帧执行没结束的代码
          如果使用递归 , 需要给与一个跳出的条件,不能无限递归
          

          尾递归:

          在函数返回的时候,调用其本身,并且,return语句不包含表达式。

          (简单来说是递归函数,且只调用自己的非表达式)

          尾递归意义:

          使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况.(需要Python解释器支持)

          尾递归流程:

          Python中的递归详解 第5张

          5.内存栈区堆区(了解内容)

          单独讲栈堆是数据结构

          栈:后进先出的一种数据结构

          堆:排序后的一种树状数据结构

          栈区堆区是内存空间

          栈区:按照后进先出的数据结构(栈),无论创建或销毁都是自动为数据分配内存,释放内存

          (系统自动做的)

          堆区:按照排序后的树状数据结构(堆),可优先取出必要数据,无论创建或销毁都是手动分配内存,释放内存(程序员手动做的)

          –内存中的栈区 : 自动分配 自动释放

          –内存中的堆区 : 手动分配 手动释放

          运行程序时在内存中执行,会因为数据类型的不同而在内存的不同区域运行

          因不同语言对内存划分的机制不一,但大体来讲,有如下四大区域

          –栈区: 分配局部变量空间.

          –堆区: 是用于手动分配程序员申请的内存空间.

          –静态区(全局栈区): 分配静态变量,全局变量空间.

          –代码区(只读区,常量区): 分配常量和程序代码空间的.

          栈区 堆区 静态区 代码区 都是内存中的一段空间

          6.递归案例

          1.使用递归实现任意数n的阶乘

          普通实现

          # 5! =5 *4*3*2*1
          n = 5
          total = 1
          for i in range(n,0,-1):
              total *= i
          print(total) # 120
          

          Python中的递归详解 第6张

          递归实现

          def jiecheng(n):
              if n  1 
          # jiecheng(2) => jiecheng(1) * 2 => 1 * 2
          # jiecheng(3) => jiecheng(2) * 3 => 1 * 2 * 3
          # jiecheng(4) => jiecheng(3) * 4 => 1 * 2 * 3 * 4
          # jiecheng(5) => jiecheng(4) * 5 => 1 * 2 * 3 * 4 * 5
          print(jiecheng(5))
          

          代码解析:

          去的过程:

          n = 5 return jiecheng(n-1) * n => jiecheng(4) * 5

          n = 4 return jiecheng(n-1) * n => jiecheng(3) * 4

          n = 3 return jiecheng(n-1) * n => jiecheng(2) * 3

          n = 2 return jiecheng(n-1) * n => jiecheng(1) * 2

          n = 1 return 1

          回的过程:

          n = 2 return jiecheng(1) * 2 => 1 * 2

          n = 3 return jiecheng(2) * 3 => 1 * 2 * 3

          n = 4 return jiecheng(3) * 4 => 1 * 2 * 3 * 4

          n = 5 return jiecheng(4) * 5 => 1 * 2 * 3 * 4 * 5

          到此程序结束:

          返回 1 * 2 * 3 * 4 * 5

          print(“”)

          2. 使用尾递归来实现任意数的阶乘

          return 在哪调用,在哪返回

          自己调用自己,且返回时非运算表达式,只是函数本身

          特点:

          尾递归只开辟一个空间,不会无限的开辟,在一个空间里面去计算最后的结果进行返回,比较节省空间,有的解释器支持尾递归的调用特点

          但是cpython解释器目前不支持

          写法:

          所有运算的值都在函数的参数中计算完毕,最后返回运算的参数;

          def jiecheng(n,endval):
              if n  jiecheng(4,51) => 51432

          n = 4 ,endval = 5

          1 return jiecheng(n-1 , n * endval) => jiecheng(3,514) => 51432

          n = 3 ,endval = 514 return jiecheng(n-1 , n * endval) => jiecheng(2,5143) => 51432

          n = 2 ,endval = 5143 return jiecheng(n-1 , n * endval) => jiecheng(1,51432) => 51432

          n = 1 ,endval = 51432 if n return 5

          feib(4) + feib(3)

          feib(3)+feib(2) feib(2)+feib(1) => 1 + 1 => 2

          feib(2)+feib(1)+feib(2) => 1 + 1 + 1 => 3

          可以直接计算出来斐波那契数列 第几个值是多少

          Python中的递归详解 第7张


    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]