递归函数:底层原理、实战案例、深度溢出与全套优化
博客导语
递归是算法基础核心,新手普遍不懂栈溢出原理、递归终止条件写法。本篇拆解函数调用栈底层,给出斐波那契、目录遍历经典案例,讲解递归深度限制、尾递归优化、迭代改写三种避坑方案。
一、递归底层原理
递归本质:函数内部调用自身。底层依靠函数调用栈实现,每递归调用一次,就会向栈内新增一个栈帧,保存局部变量、执行指针,上层函数不会结束,持续阻塞等待下层函数返回结果。
递归两大必备条件(缺一必死循环)
递归出口(终止条件):满足条件直接return,停止自我调用
递归推进:每次调用向出口靠近,参数持续收敛
二、经典零基础实战案例
案例1:递归计算阶乘
def factorial(n): # 递归出口 if n == 1: return 1 # 递归推进 return n * factorial(n-1) print(factorial(5)) # 120案例2:递归遍历本地多层目录(生产常用)
自动遍历文件夹内所有文件,无需手动嵌套循环,适配未知层级目录
三、递归深度限制与栈溢出
1.默认深度限制
Python官方默认递归最大深度为1001层(系统预留一层),超过直接抛出RecursionError栈溢出异常。可通过sys查看默认值:
import sys print(sys.getrecursionlimit()) # 默认1000 sys.setrecursionlimit(2000) # 手动修改上限2.手动修改上限治标不治本
操作系统本身有线程栈内存上限,强行修改Python限制,会直接导致程序崩溃、内存溢出,不推荐生产使用。
四、递归三大优化方案(生产落地)
方案1:尾递归优化
尾递归:递归调用是函数最后一步操作,无额外计算。栈帧可复用,不会持续占用内存。
注意:CPython官方不原生支持尾递归优化,仅理论生效,无法落地
方案2:迭代改写(最优方案)
所有递归都可以转为循环迭代,彻底消除栈溢出风险,生产优先使用
方案3:使用lru_cache缓存递归结果
解决斐波那契递归重复计算问题,提升百倍运行速度,通过装饰器缓存已经计算过的参数结果
from functools import lru_cache @lru_cache(maxsize=None) def fib(n): if n<=2: return 1 return fib(n-1)+fib(n-2)五、递归使用选型边界
适合:层级固定、树形结构、目录遍历、回溯算法;不适合:深度未知、海量数据计算,优先迭代替代
