【问题标题】:Why BST left <= parent <= right is not ideal?为什么 BST left <= parent <= right 不理想?
【发布时间】:2019-01-17 16:11:09
【问题描述】:

当允许重复时,BST 节点通常具有以下属性: 左

left

【问题讨论】:

标签: algorithm data-structures binary-search-tree


【解决方案1】:

因为您需要保持O(log n) 的复杂性进行搜索。假设您正在搜索一个节点,那么您必须在左右子树中检查它以检查它的存在。但是,正确的条件会强制执行 Node 仅存在于其中一个子树中的约束。

考虑BST节点包含IntegerString的场景,构建BST的关键是Integer

如果您需要整数 a 的所有字符串,则需要检查两个子树,如果您根据实现它,这将导致 O(n) 而不是 O(log n) 的时间复杂度更差到正确的状态。

【讨论】:

  • 如果需要进一步说明,请发表评论。
  • 注意:这并不能保证 O(log n) 的搜索复杂度 - 如果所有节点(或其中的某个常数部分)都相等,您将拥有 O (n) 任何一种方式的复杂性。它还使树的平衡性降低,因为相等的节点本质上是一个链表,这也会影响搜索其他节点的复杂性。
  • 允许两边相等节点的复杂度可能更接近 O(min(n, k log n)) (或类似的东西),其中 k 是相等节点的数量。跨度>
  • 在具有重复项的 BST 中,查找任何键的第一个或最后一个值所花费的时间与高度成正比——没有检查双方。遍历高度为 h 的树中键的所有 m 值需要 O(h+m)。无论您如何将相等的节点链接在一起,只要保持 BST 属性,这些都是正确的。我不认为这个答案的任何部分是正确的
  • @Dukeling 我同意这会导致树结构效率低下,并且不能保证 O(log n) 搜索复杂度。然而,据我所知,我试图分享的是这种情况背后的直觉。你和马特的 cmets 都对拓宽我的范围很有见地。谢谢。
【解决方案2】:

如果 left

【讨论】:

  • 最初插入元素时看起来像这样,但是当重新平衡树时(如果你插入足够多的相同元素肯定会如此),你最终会得到两个链接的相同节点父母双方。
【解决方案3】:

你的前提不正确。在允许重复的 BST 中,它总是 left 。选择插入新节点的位置的代码只会选择一侧或另一侧,但这不是关于节点必须如何链接的规则,它不是将被维护的不变量。

这是因为,对于具有重复值的树,左或右分支仅包含严格较大的元素的条件与平衡操作不兼容。试试这个:将相同值的 20 个副本链接到树中。如果您只能在左侧或右侧链接相等的值,那么您必须创建一个单链表。您的树将有 20 层深且完全不平衡。

考虑树中重复值的方法是,树中实际上没有任何重复值 :-) BST 定义了总排序,而有效的重新平衡操作(如旋转)会保留此总排序。

在树中插入重复项时,会将其放在现有匹配项的左侧或右侧。如果你把它放在左边,那么它会根据树的顺序变小,并且在任何重新平衡后它总是会变小。如果你把它放在右边,那么它会更大,并且会根据树的顺序保持更大。

如果您考虑一下,它必须是这样的,因为平衡操作和中序遍历甚至不查看节点中的值。它们链接在一起的方式决定了排序,排序不会随着树的重新平衡而改变,并且排序是完全的——在中序遍历中,每个节点都在每个其他节点之前或之后。

【讨论】:

  • 感谢您的回答。 DS 课程中没有教给我们这一点。我喜欢!
  • 我明白你在说什么,但是“二叉搜索树”的定义并不能保证重新平衡是一件事,或者任何特定类型的重新平衡操作都必然被认为是“有效的”。因此,您的答案非常实用——它适用于大多数现实世界的 BST(通常是红黑树或 AVL 树等)——但并不像它声称的那样明确。
  • @ruakh,这里的“总是”是指“在每个现实情况下”。我认为这是合理的,因为这是一个关于编程(一门实用艺术)而不是数学的网站。
  • @MattTimmermans:但您的答案对于每个 实际情况并不正确,仅适用于大多数 实际情况。 (非重新平衡的 BST 确实存在于野外,并且可以很好地用于许多目的。)“总是”是一种夸张的说法。
猜你喜欢
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 2019-08-18
  • 1970-01-01
  • 2019-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多