【发布时间】:2021-03-28 13:46:00
【问题描述】:
我对递归的主要关注是 Python 中的递归限制,我认为是 1000。考虑到这一点,我想讨论两种情况:
场景 1:对平衡树应用递归(二叉树)
例如,在树中搜索最大值:
class Node:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
def max(root):
max_left = max(root.left)
max_right = max(root.right)
if max_left > root.value and max_left > max_right:
return max_left
if max_right > root.value and max_right > max_left:
return max_right
else:
return root.value
在这里,在任何给定时间堆栈中的最大调用数将是树的高度,即 log_2(n),其中 n 是列表中的元素数。鉴于 Python 中的限制是 1000 次调用,树可以存储多达 2^1000(或 2^999)个元素而不会达到调用限制。对我来说,这不是一个真正的限制,所以我假设我们可以在这里使用递归。
场景 2:对列表应用递归
一个虚拟的例子是计算一个列表的最大值,因此我们返回列表的头部和列表其余部分的相同函数的结果之间的最大值:
def max(l):
if len(l) == 1:
return l[0]
max_tail = max(l[1:])
if l[0] > max_tail:
return l[0]
else:
return max_tail
输出:
>>> max(list(range(998)))
997
>>> max(list(range(999)))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in max
File "<stdin>", line 4, in max
File "<stdin>", line 4, in max
[Previous line repeated 995 more times]
File "<stdin>", line 2, in max
RecursionError: maximum recursion depth exceeded while calling a Python object
所以我的理解是,对于列表递归不是一个合理的选择,因为它通常不能处理大于 999(甚至更少,取决于堆栈跟踪)的列表。
现在,我的问题:
- 使用递归处理平衡树是否合理?
- 对于大多数问题,它确实不是一个选项(列表、非平衡树等)吗?
- 还有什么我应该考虑的吗?我只是想更多地了解在使用 Python 时,递归何时是一般的好选择。
【问题讨论】:
-
如果你计算一个特定大小的平衡树需要多少次递归,并将其与递归限制进行比较,你会得到 1 的答案。
-
@Carcigenicate 在 Python 函数调用限制方面我们没问题。但是使用迭代版本不是更节省空间吗?你们通常对此类任务使用递归吗?
-
对于树的第一种情况,如果我确定没有办法超过限制,是的,我会在那里使用递归。这比我自己维护一个堆栈来做同样的工作要整洁得多。如果我发现空间是一个问题,那么我会在处理之后将其转换为迭代版本。对于列表,不,我绝对不会使用递归。简单的迭代会好很多。
标签: python recursion big-o space-complexity