【问题标题】:Binary Tree Node Location and Helper Dictionary二叉树节点位置和帮助字典
【发布时间】:2019-04-14 14:28:27
【问题描述】:

感谢您的帮助

背景

我有一个关于在树中定位节点的问题。

我有一个简单的二叉树。每个节点中都有一条数据。假设它看起来像这样:

  a
 / \
b   c

在哪里a=rootb=root.leftc=root.right

树不是手动创建的。假设我收到一个将 new_data 添加到节点 c 的请求。

我很困惑如何在不明确写 root.right.data=new_data 的情况下知道 c 在哪里。

我的第一个想法是创建某种类型的辅助字典,其中包含对节点位置的引用,例如:

helper = {
    'a'= root,
    'b'= root.left,
    'c'= root.right
}

这样当我收到请求时,我可以去找助手并说一些大意的东西:

helper.get('c').data=new_data

问题

我在这里是正确的吗?递归地反复搜索整棵树似乎有点多 - 当树改变其节点结构时,这个助手可能会偶尔更新。

当我递归爬取树时,我对如何实际返回每个节点的位置感到困惑。如何创建这个助手?

【问题讨论】:

  • 你可以看看这个答案:stackoverflow.com/questions/2598437/…
  • 为什么仍然需要树?为什么不把你的数据放在字典里,仅此而已?
  • @SchiduLuca 我已经大大简化了这个例子。树提供了父对象和子对象之间的关键链接,它们可以以不同的方式相互作用。树为此提供了一个非常好的结构。我不相信字典会很有成效。
  • @JW2 Recursively searching an entire tree repeatedly seems a bit much 。如果您决定以这种形式放置数据,则可以递归遍历。如果您认为这太多了,那就根本不要使用树..

标签: python recursion binary-tree binary-search-tree


【解决方案1】:

如果你有对节点c的引用,你可以直接使用它,比如c.data=new_data

否则,如果你得到的是例如一个字符串,然后:

  1. 您的树是否已排序,或者可以排序? (即它是 BST 吗?)如果是,请使用它。
  2. 如果不是,那么树/节点的任何其他属性可用于修剪搜索吗? (即您有一些信息可以限制搜索的位置)。如果是这样,请使用它。如果您不知道是否可以使用它,您应该在问题中指定您的数据具有的任何属性。
  3. 如果节点可以在任何地方,那么您几乎必须搜索整个树(因为您想要的节点可以在任何地方)。如果是这种情况,那么树结构是否有目的?也许哈希表可能有用。 (您可以在获取树后对其进行索引)

顺便说一句。请注意,搜索树的大小应为 O(n),这取决于您是否过多。

【讨论】:

  • 这是一个 BST。每个节点都有一个唯一的标识符。我认为你是对的 - 无论我是在为那个键 helper.get(key) 搜索帮助字典,还是在遍历树我仍在搜索。当我搜索它时如何返回节点的实例对我来说并不是很明显。
  • 啊,在这种情况下,您可以参考 Ivonet 链接的这个答案stackoverflow.com/a/28864021/272515 中的 _find() 方法(请注意,它实际上并没有使用 self 除非递归地引用 _find 方法。所以为您的目的转换为函数应该是微不足道的)
【解决方案2】:

回答

答案是递归搜索。我对助手 dict 的想法源于我对 BST 的不熟悉。我将以下内容添加到我的节点以搜索树的预排序:

def find_node(self, start, id):
    if start:
        if start.id == id:
            return start
        else:
            node = self.find_node(start.left, id)
            if node:
                return node
            else:
                node = self.find_node(start.right, id)
                if node:
                    return node
    else:
        return None

This video 对帮助我理解 BST 非常有帮助。我意识到,当我找到正确的id 时,我可以返回类本身的实际实例,而不是仅仅打印遍历。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-11
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    • 2020-08-03
    • 1970-01-01
    相关资源
    最近更新 更多