前言
python 3递归极容易爆栈。
经过测试,python 3在linux上的最大递归层数为998。
如图所示。
a.py
def funs(p,n):
if p == n:return
funs(p + 1,n)
funs(1,int(input()))
但是在实际应用中,递归层数突破上限可能不可避免,这是该怎么办呢?
解决方案
函数的递归操作涉及到内存中栈的使用,函数的递归深入和返回对应着相关数据的入栈和出栈,因此我们可以尝试使用栈结构来模拟函数的递归过程。
如下所示。
递归代码
def dfs(idx,p):
D[idx] = D[p] + V[idx]
for u in A[idx]:
if u == p: continue
dfs(u,idx)
模拟递归代码
from collections import deque
def dfs(idx,p):
q = deque()
q.append((idx,p))
while q:
idx,p = q.pop()
D[idx] = D[p] + V[idx]
for u in A[idx]:
if u == p: continue
q.append((u,idx))
两个代码的功能一致,唯一的差别是第二个代码比第一个代码可递归的层数多得多。
优化后的代码看起来有点类似于广度优先搜索的风格,因为深搜和广搜在实际的代码上可以仅仅是一个存储容器的差别——深搜对应栈,广搜对应队列(但在C++等其他栈空间比较大的语言中一般我们使用函数递归替代栈来简化代码)。
因此我们可以使用广搜的格式编写需要递归的算法。
或者将原始递归代码编写好后,再做修改——将递归变成入栈,将函数返回变成出栈即可。
注:
- 因为python 3中deque的入队出队效率相比于列表更高,所以优先采用deque作为模拟栈的容器。
- 本方法在递归逻辑比较简单时比较适合用。当递归存在返回值和递归逻辑比较复杂时不太适合。
原创不易,感谢支持。