如何将以下函数变成尾递归函数?
How can I make the following function into a tail-recursive function?
我一直在跟进 here,我正在尝试练习将普通递归函数转换为尾递归函数。我设法理解了斐波那契数列和阶乘的版本,但这一个难倒了我。我了解算法在做什么,以及在转换过程中让我感到困惑的 else 语句。
在 else 内部,它会尝试找到一个更接近您正在寻找的数字,然后放弃并使用它发现的小于您建议的数字。
我不确定如何编写使此尾部递归的辅助函数。对于斐波那契和阶乘,我最终使用了累加器。有没有类似的东西可以用在这里?
class BSTNode(object):
"""Binary search tree node."""
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
def __repr__(self):
return '(%s, %r, %r)' % (self.val, self.left, self.right)
def find_val_or_next_smallest(bst, x):
"""
Get the greatest value <= x in a binary search tree.
Returns None if no such value can be found.
"""
if bst is None:
return None
elif bst.val == x:
return x
elif bst.val > x:
return find_val_or_next_smallest(bst.left, x)
else:
right_best = find_val_or_next_smallest(bst.right, x)
if right_best is None:
return bst.val
return right_best
我知道 Python 不支持尾递归优化以允许常量堆栈 space 但我这样做只是为了在 Python 中练习,因为我喜欢语法
而不是做
if right_best is None:
return bst.val
您可以将迄今为止找到的最佳结果作为额外参数传递给递归调用,并让递归调用处理此检查。
def find_val_or_next_smallest(bst, x, best=None):
"""
Get the greatest value <= x in a binary search tree.
Returns None if no such value can be found.
"""
if bst is None:
return best
elif bst.val == x:
return x
elif bst.val > x:
return find_val_or_next_smallest(bst.left, x, best)
else:
# bst.val is guaranteed to be the best yet, since if we had
# seen a better value higher up, the recursion would have gone
# the other way from that node
return find_val_or_next_smallest(bst.right, x, bst.val)
要将函数转换为尾递归,您应该通过添加一个额外的参数 val
:
将部分答案随身携带
def find_val_or_next_smallest(bst, x, val=None):
"""
Get the greatest value <= x in a binary search tree.
Returns None if no such value can be found.
"""
if bst is None:
return val
elif bst.val == x:
val = x
elif bst.val < x and (val is None or bst.val > val):
val = bst.val
if bst.val > x:
return find_val_or_next_smallest(bst.left, x, val)
else:
return find_val_or_next_smallest(bst.right, x, val)
更新
尾递归意味着我们可以有一个迭代解决方案(相对于递归),并且可以很容易地在 上演示 - 通过将其转换为迭代解决方案:
def find_val_or_next_smallest(bst, x, val=None):
"""
Get the greatest value <= x in a binary search tree.
Returns None if no such value can be found.
"""
while True:
if bst is None:
return val
elif bst.val == x:
return x
elif bst.val > x:
bst = bst.left
else:
val = bst.val
bst = bst.right
我一直在跟进 here,我正在尝试练习将普通递归函数转换为尾递归函数。我设法理解了斐波那契数列和阶乘的版本,但这一个难倒了我。我了解算法在做什么,以及在转换过程中让我感到困惑的 else 语句。
在 else 内部,它会尝试找到一个更接近您正在寻找的数字,然后放弃并使用它发现的小于您建议的数字。
我不确定如何编写使此尾部递归的辅助函数。对于斐波那契和阶乘,我最终使用了累加器。有没有类似的东西可以用在这里?
class BSTNode(object):
"""Binary search tree node."""
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
def __repr__(self):
return '(%s, %r, %r)' % (self.val, self.left, self.right)
def find_val_or_next_smallest(bst, x):
"""
Get the greatest value <= x in a binary search tree.
Returns None if no such value can be found.
"""
if bst is None:
return None
elif bst.val == x:
return x
elif bst.val > x:
return find_val_or_next_smallest(bst.left, x)
else:
right_best = find_val_or_next_smallest(bst.right, x)
if right_best is None:
return bst.val
return right_best
我知道 Python 不支持尾递归优化以允许常量堆栈 space 但我这样做只是为了在 Python 中练习,因为我喜欢语法
而不是做
if right_best is None:
return bst.val
您可以将迄今为止找到的最佳结果作为额外参数传递给递归调用,并让递归调用处理此检查。
def find_val_or_next_smallest(bst, x, best=None):
"""
Get the greatest value <= x in a binary search tree.
Returns None if no such value can be found.
"""
if bst is None:
return best
elif bst.val == x:
return x
elif bst.val > x:
return find_val_or_next_smallest(bst.left, x, best)
else:
# bst.val is guaranteed to be the best yet, since if we had
# seen a better value higher up, the recursion would have gone
# the other way from that node
return find_val_or_next_smallest(bst.right, x, bst.val)
要将函数转换为尾递归,您应该通过添加一个额外的参数 val
:
def find_val_or_next_smallest(bst, x, val=None):
"""
Get the greatest value <= x in a binary search tree.
Returns None if no such value can be found.
"""
if bst is None:
return val
elif bst.val == x:
val = x
elif bst.val < x and (val is None or bst.val > val):
val = bst.val
if bst.val > x:
return find_val_or_next_smallest(bst.left, x, val)
else:
return find_val_or_next_smallest(bst.right, x, val)
更新
尾递归意味着我们可以有一个迭代解决方案(相对于递归),并且可以很容易地在
def find_val_or_next_smallest(bst, x, val=None):
"""
Get the greatest value <= x in a binary search tree.
Returns None if no such value can be found.
"""
while True:
if bst is None:
return val
elif bst.val == x:
return x
elif bst.val > x:
bst = bst.left
else:
val = bst.val
bst = bst.right