Algorithm 范围树:为什么默认情况下不保存空间?

Algorithm 范围树:为什么默认情况下不保存空间?,algorithm,data-structures,binary-search-tree,range-tree,Algorithm,Data Structures,Binary Search Tree,Range Tree,假设在二维平面上有一组唯一点。现在,您需要一系列问题,形式为“点p是否存在于S中?”您决定构建一个范围树来存储S,然后回答此问题。范围树背后的基本思想是,首先在0-th坐标上构建一个平衡的二元搜索树Tree0,然后在此Tree0的每个节点上构建另一个平衡的搜索树Tree1,但这次使用1-st坐标作为键 现在,我希望为Tree0的每个节点n0构建的Tree1将准确地包含那些0次坐标等于n0中的键的点。但是,如果您阅读更多关于范围树的内容,您会发现情况并非如此。具体而言: Tree0的根r0包含一个

假设在二维平面上有一组唯一点。现在,您需要一系列问题,形式为“点
p
是否存在于
S
中?”您决定构建一个范围树来存储
S
,然后回答此问题。范围树背后的基本思想是,首先在
0-th
坐标上构建一个平衡的二元搜索树
Tree0
,然后在此
Tree0
的每个节点上构建另一个平衡的搜索树
Tree1
,但这次使用
1-st
坐标作为键

现在,我希望为
Tree0
的每个节点
n0
构建的
Tree1
将准确地包含那些
0次
坐标等于
n0
中的键的点。但是,如果您阅读更多关于范围树的内容,您会发现情况并非如此。具体而言:

  • Tree0
    的根
    r0
    包含一个保存所有点的
    Tree1
  • r0
    的左子级包含一个
    Tree1
    ,其中包含
    0-th
    坐标小于
    r0
    0-th
    坐标的所有点
  • r0
    的右子级包含一个
    Tree1
    ,其中包含
    0-th
    坐标大于
    r0
    坐标的所有点
  • 如果继续此逻辑,您将看到在范围树的每个级别上,所有点都只存储一次。因此,每个级别都需要
    n
    内存,并且由于平衡
    Tree0
    的深度是
    logn
    ,这就给出了
    O(nlogn)
    作为内存需求

    但是,如果只存储第0个坐标与节点上的关键点完全匹配的点,则每个点将在整个树中存储一次(而不是在树的每个级别),这将给出
    O(n)
    内存需求

    在范围树中每个级别存储一次点的原因是什么?它是否允许一些冷范围查询或其他什么?到目前为止,在我看来,您可以对
    O(nlogn)
    版本执行的任何查询也适用于
    O(n)
    版本。我错过了什么

    (将@user3386109的评论扩展为完整答案。)

    有几种不同的数据结构用于存储点的二维集合,每种数据结构都针对不同类型的查询进行了优化。顾名思义,范围树针对范围搜索进行了优化,查询形式为“这是一个矩形,该矩形中的所有点是什么?”范围树的结构(将每个点存储在几个不同的子树中)设计为可以在1D中找到包含一个矩形轴的节点跨度,然后发现下一维度中矩形另一维度中的所有节点。如果您不打算对该表单进行任何查询,那么就没有必要以这种方式存储东西。你基本上是在为你不打算使用的东西付费

    您还可以使用其他数据结构来存储一组点,并查看是否存在特定点。如果这是您需要回答的唯一问题,那么您可能只需要使用一个简单的哈希表。您还可以使用常规的BST,其中首先通过点的第一个组件比较点,然后通过点的第二个组件进行比较。(如果您愿意,也可以在此处使用k-d树。)


    希望这有帮助

    二维距离树回答的问题是:“给定矩形中包含多少个点?”您试图回答的问题是:“点p是否存在于集合S中?”这是两个截然不同的问题。您肯定不会使用范围树来回答第二个问题。