假设您S
在二维平面上有一组独特的点。现在,您期待着一堆“点p
存在于S
?”形式的问题。你决定建立一个范围树来存储你的S
问题并回答这个问题。范围树背后的基本思想是,您首先Tree0
在0-th
坐标上构建平衡二叉搜索树,然后在此构建的每个节点上再Tree0
构建另一个平衡搜索树Tree1
,但这次使用1-st
坐标作为键。Range Tree 的维基百科文章。
现在,我期待Tree1
为 的每个节点构建的n0
那些Tree0
点将准确地保存其0-th
坐标等于键 from 的那些点n0
。但是,如果您阅读有关范围树的更多信息,您会发现情况并非如此。具体来说:
- 的根
r0
包含Tree0
包含Tree1
所有点的 a。 - 的左孩子
r0
包含 aTree1
,其中包含0-th
坐标小于0-th
处坐标的所有点r0
。 - 的右孩子
r0
包含 aTree1
,其中包含0-th
坐标大于 from的所有点r0
。
如果你继续这个逻辑,你会看到在 Range Tree 的每一层,所有的点都只存储一次。因此,每个级别都需要n
内存,并且由于平衡的深度Tree0
是logn
,这O(nlogn)
就是内存要求。
但是,如果您只存储其0-th
坐标与节点处的键完全匹配的点,那么您将在整个树(而不是树的每个级别)中存储每个点一次,这会产生O(n)
内存需求。
在范围树中每个级别存储一次点的原因是什么?它是否允许某种很酷的范围查询或其他东西?到目前为止,在我看来,您可以对该版本执行的任何查询O(nlogn)
也适用于该O(n)
版本。我错过了什么?