Python中的有序遍历

Python中的有序遍历,python,recursion,data-structures,binary-search-tree,inorder,Python,Recursion,Data Structures,Binary Search Tree,Inorder,我要解决的问题是在BST中的顺序遍历中找到第一个出现的节点。 下面给出了我的代码 def Inorder_search_recursive(node,key): if not node: return None InOrder_search_recursive(node.lChild) if node.value==key: return node InOrder_search_recursive(node.rChild) 这段代

我要解决的问题是在BST中的顺序遍历中找到第一个出现的节点。 下面给出了我的代码

def Inorder_search_recursive(node,key):
    if not node:
        return None
    InOrder_search_recursive(node.lChild)
    if node.value==key:
        return node
    InOrder_search_recursive(node.rChild)

这段代码总是返回None,有什么问题吗。当我找到一个值为k的节点时,我想我已经返回了node。为什么python无法通过此节点???当您递归调用自己时,请提前感谢,如下所示:

InOrder_search_recursive(node.lChild)
这只是一个普通的函数调用,就像其他调用一样。它只是调用函数并返回一个结果。它不会自动
返回该函数的值,也不会执行任何其他操作

因此,您执行左子树搜索,忽略结果,然后继续检查
node.value==key
,如果失败,则执行右子树搜索,再次忽略结果,并从函数末尾退出,这意味着您返回
None

要使其工作,您需要
返回返回的值。但是,当然,只有当它是
而不是None

另外,您忘了将
参数向下传递给递归调用,因此您将得到一个
类型错误
。(我猜您的真实代码没有这个问题,但由于您没有向我们展示您的真实代码或工作示例,我不能确定……)

因此:


(您不需要检查右侧搜索的
not None
,因为如果它返回
None
,我们就没有其他方法可以尝试了,反正只会返回
None

当您递归调用自己时,如下所示:

InOrder_search_recursive(node.lChild)
这只是一个普通的函数调用,就像其他调用一样。它只是调用函数并返回一个结果。它不会自动
返回该函数的值,也不会执行任何其他操作

因此,您执行左子树搜索,忽略结果,然后继续检查
node.value==key
,如果失败,则执行右子树搜索,再次忽略结果,并从函数末尾退出,这意味着您返回
None

要使其工作,您需要
返回返回的值。但是,当然,只有当它是
而不是None

另外,您忘了将
参数向下传递给递归调用,因此您将得到一个
类型错误
。(我猜您的真实代码没有这个问题,但由于您没有向我们展示您的真实代码或工作示例,我不能确定……)

因此:


(您不需要对右侧搜索进行
not None
检查,因为如果它返回
None
,那么我们就没有其他方法可以尝试了,只需要返回
None

因为您的问题是
在其顺序遍历中查找第一个出现的节点,您应该1)按顺序遍历树,2)在找到第一个匹配项时停止

def search(node, key):
    if node is None:
        return None
    # Search the left subtree and return early if key is found
    n = search(node.lChild, key)
    if n is not None:
        return n
    # Check middle and return early if key is found
    if node.value == key:
        return node
    # Search right subtree
    return search(node.rChild, key)

由于您的问题是要在索引遍历中找到第一个出现的节点,因此您应该1)按顺序遍历树,2)在找到第一个出现的节点时停止

def search(node, key):
    if node is None:
        return None
    # Search the left subtree and return early if key is found
    n = search(node.lChild, key)
    if n is not None:
        return n
    # Check middle and return early if key is found
    if node.value == key:
        return node
    # Search right subtree
    return search(node.rChild, key)

我的另一个答案给出了新手友好的解决方案,但如果您想要更强大、更简洁的答案:

def Inorder_search_recursive_all(node, key):
    if not node:
        return
    yield from InOrder_search_recursive(node.lChild, key)
    if node.value==key:
        yield node
    yield from InOrder_search_recursive(node.rChild, key)
这将按顺序生成树中的所有匹配项。它将它们作为迭代器提供给您,因此如果您只需要第一个迭代器,您可以在找到一个迭代器后立即停止,而不会浪费工作:

def Inorder_search_recursive(node, key):
    return next(Inorder_search_recursive_all(node, key), None)

关于生成器的教程部分和下面关于生成器的部分解释了大部分工作原理。唯一缺少的一点是
中对
收益率的解释。

我的另一个答案给出了新手友好的解决方案,但如果您想要更强大、更简洁的答案:

def Inorder_search_recursive_all(node, key):
    if not node:
        return
    yield from InOrder_search_recursive(node.lChild, key)
    if node.value==key:
        yield node
    yield from InOrder_search_recursive(node.rChild, key)
这将按顺序生成树中的所有匹配项。它将它们作为迭代器提供给您,因此如果您只需要第一个迭代器,您可以在找到一个迭代器后立即停止,而不会浪费工作:

def Inorder_search_recursive(node, key):
    return next(Inorder_search_recursive_all(node, key), None)

关于生成器的教程部分和下面关于生成器的部分解释了大部分工作原理。唯一缺少的一点是对
收益率的解释,这在中进行了解释。

如果这是一个二元搜索树,您可能会通过实际的二元搜索而不是顺序搜索得到更好的结果。是的,您是对的,我刚刚弄明白了,我们可以首先使用value key找到该值。我们可以使用BST的属性来节省大量时间。然后搜索其左子树。如果它的左子树也有一个带值键的节点,则立即返回。如果这是一个二元搜索树,使用实际的二元搜索而不是顺序搜索可能会得到更好的结果。是的,你是对的,我刚刚计算出来,我们可以先用值键找到该值。我们可以使用BST的属性来节省大量时间。然后搜索其左子树。如果其左子树也有一个带值键的节点,则立即返回。