这个递归BST算法的基本情况是什么



我并不经常编写递归函数/方法。我成功地理解了";基本情况";在更简单的功能中,如以下:

def countdown(num):
if num == 0: # Base case
return
print(num) # Action
countdown(num-1) # Reduction and recurse
def factorial(num):
if num == 0 or num == 1: # Base cases
return 1
return factorial(num-1) * num # reduction + recurse + action

然而,我已经编程了一种算法,可以在二进制搜索树(BST(中找到最接近给定值的值,以及插入、打印所有节点和其他此类算法。我发现这些算法更难理解,尤其是在识别基本情况方面。这个问题具体涉及以下findClosest_findClosest的实现。考虑:

class BSTNode:
def __init__(self,value=None):
self.value = value
self.leftChild = None
self.rightChild = None
class BST:
def __init__(self):
self.root = None
def findClosest(self, value):
if self.root is None: # Base case 0
print("There is no tree, so can't find closest!")
return None
else:
return self._findClosest(value, self.root, self.root.value)
def _findClosest(self, searchValue, currentNode, closest):
if currentNode is None: # Base case #1
return closest 
if abs(currentNode.value - closest) < abs(closest - searchValue): # ACTION
closest = currentNode.value
if searchValue > currentNode.value: # Reduce and recurse
return self._findClosest(searchValue,currentNode.rightChild, closest)
elif searchValue < currentNode.value: # Reduce and recurse
return self._findClosest(searchValue,currentNode.leftChild,closest)
else:
return currentNode.value # Base case #2

您可以看到,我试图识别基本情况。当我使用一种";驱动程序,伪公共";方法分别处理无根的第一个基本情况;基本情况0";。无论如何,我的困惑点是_findClosest()中有4个独立的返回语句,而我目前对recision的了解会让我猜测,我用注释标记的Base case #1Base case #2实际上是该方法中仅有的两个基本情况。然而,为了使该方法正确工作,当对leftChildrightChild调用时,我还必须返回_findClosest()的结果,所以这些也会是更多的基本情况吗我很难确定什么是基本情况,什么是减少/递归步骤存在多个基本情况和单独的";递归路径";如果你愿意的话,对我来说要比我前面提到的那些简单的递归函数更难理解。最后,_findClosest方法中的基本情况也被展开,递归调用夹在中间,这进一步增加了我的困惑。

请注意,提供的代码在Python 3.7.9上运行良好,但我故意不包括其余的BST方法和驱动程序,因为我担心包含太多代码。我也不确定这个问题是否需要这些剩余的项目。如果有合适的答案,我会编辑并添加它们

对于递归函数,任何不需要递归计算的状态都可以是基本情况。即使计算基值需要一些计算(不是递归的(,它也符合基本情况,因为它在那里结束了递归。

类似地,任何进行或不进行任何计算但对某个子状态进行递归调用的语句都可以被限定为递归步骤(减少取决于计算;如果搜索空间不减少,从技术上讲,你将陷入无限递归(。

至于您的实现,您已经正确地对_findClosest()中的语句进行了分类。然而,findClosest()的分类没有多大意义,因为它无论如何都不是递归函数。

来自

https://www.sparknotes.com/cs/recursion/whatisrecursion/section1/page/3/

函数的基本情况或停顿情况是我们知道答案的问题,可以在没有任何递归调用的情况下解决。基本情况是阻止递归永远继续下去的原因。每个递归函数都必须至少有一个基本情况(许多函数都有多个(。

使用left_childright child调用递归函数_findClosest时,不确定是否找到了最接近的searchValue。当其中一个基本情况发生时(currentNode为Null或currentNode.value==searchValue(,您一定会找到最接近的数字。

顺便说一句,您可以很容易地将函数_findClosest实现为迭代函数(因为您从未让函数在堆栈上调用,所以"_findClosest"从未两次调用过自己(。

我认为你在比较中犯了一个错误,当你想看看searchValue是否更接近currentNode.value,而不是closest:

if abs(currentNode.value - closest) < abs(closest - searchValue):

应该是:

if abs(currentNode.value - searchValue) < abs(closest - searchValue):

最新更新