【问题标题】:What is the best way to implement this type of binary tree?实现这种二叉树的最佳方法是什么?
【发布时间】:2011-11-30 06:20:59
【问题描述】:

假设我有一棵高度为 h 的二叉树,其元素为 x1、x2、... xn。

xi 元素最初位于第 i 个最左边的叶子。树应该在 O(h) 时间内支持以下方法

  1. add(i, j, k) 其中 1

  2. get(i):返回第i个最左边叶子的值。

该属性的内部节点应该存储什么?

注意:我不是在寻找确切的答案,但任何关于如何解决问题的提示都会很好。

【问题讨论】:

  • 这是作业吗?如果是这样,您可以将标签作业添加到您的问题中吗?谢谢你:)

标签: algorithm data-structures binary-tree


【解决方案1】:

据我了解,第 xi 个元素的 位置 永远不会改变,而且树不是搜索树,搜索仅基于节点的位置。

可以在非叶子顶点中存储一个偏移量,表示其后代的值变化。

add(i,j,k) 将从根开始,在树中加深,当且仅当它的所有后代都在[i,j] 范围内时,将节点的值增加 k。如果它增加了该值,则不会发生进一步的加深。
注意1:在单个add() 操作中,您可能需要添加多个数字。
注意 2: 实际上,您最多需要添加 O(logn) = O(logh) 值 [说服自己为什么。提示:直到n 的数字的二进制表示需要O(logn) 位],这稍后会告诉你[再次,确保你理解为什么]O(logh) 需要复杂性。

get(i) 然后是微不足道的:总结从根到第 i 个叶子的值,然后返回这个总和。

由于这似乎是作业,我不会发布伪代码,本指南应该可以帮助您开始这项作业。

【讨论】:

  • 在“当且仅当 ...”部分中,您是否假设节点按顺序遍历?
  • 你正在增加一个非叶子节点的值,你可以随意遍历它,inorder只是一种可能,无论如何,你不需要遍历超过2*h顶点,最多 2 个叶子。
  • 实际上,我需要为每个内部节点存储最多 O(1) 的空间。我知道 Knuth 有一个聪明的算法来迭代 O(1) 辅助空间中的二叉树,时间为 O(nlogn):stackoverflow.com/questions/791052/… 所以我正在考虑将此解决方案转换为我的解决方案,但看不到如何......也许暂时添加来自某些叶子的反向引用以某种方式可以解决问题,因为 add() 操作不返回任何内容.. 它只是帮助我回答 get(i) 操作..
  • 每个内部节点都需要O(1) 空间,只是每个节点的偏移值。此外,您可以确保算法使用O(1) 空间运行,如果您向每个顶点添加一个额外的“父”节点,如果没有它,递归会导致O(h) 总空间,平均为O(1) 节点, 因为h <= n.
  • 阿米特,你错过了我评论的重点。 Re "当且仅当节点的所有后代都在 [i,j] 范围内时,将节点的值增加 k" -- 在中序遍历中,如果节点的所有后代都在范围内,则该节点也是。在前序或后序遍历中,节点的所有后代都在范围内,节点本身可能在范围内,也可能不在范围内。
猜你喜欢
  • 2020-12-15
  • 2020-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多