Python二叉树搜索

时间:2018-03-21 12:43:11

标签: python recursion binary-tree

# stack_depth is initialised to 0
def find_in_tree(node, find_condition, stack_depth):
    assert (stack_depth < max_stack_depth), 'Deeper than max depth'
    stack_depth += 1
    result = []
    if find_condition(node):
        result += [node]
    for child_node in node.children:
        result.extend(find_in_tree(child_node, find_condition, stack_depth))
    return result

我需要帮助理解这段代码。我想回答的问题是

上面的Python函数搜索平衡二叉树的内容。  如果假设上限为1,000,000个节点,那么max_stack_depth常量应该设置为什么?

据我所知,这是一个棘手的问题。如果你考虑一下,每次在递归中调用find_in_tree()函数时,stack_depth都会递增。我们正试图在树中找到一个特定的节点。在我们的例子中,即使我们找到了正确的节点,我们每次都访问每个节点。因为在找到正确的节点时停止算法时没有返回条件。因此,max_stack_depth应该是1,000,000?

有人可以试着向我解释他们的思考过程。

2 个答案:

答案 0 :(得分:1)

  

如果你看看stack_depth何时递增,那么看起来我们每次访问节点时都会递增。在我们的例子中,我们每次都访问每个节点。因为在找到正确的节点时停止算法时没有返回条件。

这是不正确的。虽然 a stack_depth变量对于每个检查的节点都会增加,但它不是相同的 stack_depth变量。 stack_depth是函数中的本地。当find_in_tree递归并且递归调用递增stack_depth时,此不会更改调用者中stack_depth的值。

stack_depth正在测量此函数运行完成时发生的递归级别。它所采用的最大值将是您正在检查的树的最大深度。

那就是说,如果你知道的是你有一百万个节点,你仍然需要将max_stack_depth增加到一百万以保证断言不会失败,因为你不知道形状是什么树有。可能每个节点都只有一个孩子。在这种情况下,您需要递归大约一百万次(可能是999,999次,具体取决于您的计算方式)来访问每个节点。

当然,Python会在你到达目的地之前就阻止你。

幸运的是,你也知道树是平衡的。这意味着许多节点有两个孩子。这告诉您,您将找到的最大深度应该接近节点数的对数基数2。

答案 1 :(得分:1)

要注意的关键是stack_depth向下传递给函数的每次递归调用。如果它是一个平衡的二叉树,则每次调用find_in_tree都会将相同的stack_depth值传递给最多两个孩子。请注意,stack_depth的后续调用之间不会共享对find_in_tree的引用。他们将自己的stack_depth版本初始化为父调用的值。

这应该是足够的信息,以确定在断言触发之前该值应该是什么。