我正在寻找范围搜索的一些数据结构。我认为范围树提供了很好的时间复杂度(但有一些存储要求)。
然而,在我看来,其他数据结构,如 KD-trees ,比范围树更受讨论和推荐。这是真的?如果是这样,为什么?
答案 0 :(得分:1)
我希望这是因为kd-tree可以直接扩展为包含除点之外的对象。这给了它许多应用,例如,虚拟世界,我们想要快速查询三角形。范围树的类似扩展并不简单,实际上我从未见过任何。
快速回顾一下:kd-tree可以在O(n log n)时间内将d空间中的一组n个点预处理到使用O(n)空间的结构中,这样任何d维范围查询可以在O(n 1-1 / d + k)时间内回答,其中k是答案的数量。范围树需要O(n log d-1 n)时间进行预处理,取O(n log d-1 n)空间,并且可以在O中回答范围查询(log d-1 n + k)时间。
如果我们谈论的是2维或3维空间,那么范围树的查询时间显然要比kd树的查询时间好很多。然而,kd树有几个优点。首先,它始终只需要线性存储。其次,它总是在O(n log n)时间内构造。第三,如果维度非常高,它将胜过范围树,除非您的点集非常大(尽管可以说,此时线性搜索几乎与kd树一样快)。
我认为另一个重要的一点是,人们比野外树更了解kd树。在参加计算几何学课程之前,我从未听说过一个范围树,但我之前听说过并使用过kd-trees(尽管是在计算机图形设置中)。
编辑:当你有数百万点时,你会问为什么是2D或3D固定半径搜索的更好的数据结构。我真的不能告诉你!如果你执行很多查询,我倾向于说范围树会更快,但是对于3D来说,构造将慢一点O(log n),并且在速度之前内存使用可能会成为一个问题。我建议集成两种结构的良好实现,并简单地测试哪种方法可以更好地满足您的特定需求。
答案 1 :(得分:0)
根据您的需要(2D或3D粒子模拟),您需要一个能够进行所有最近邻查询的数据结构。封面树是最适合此任务的数据结构。我在计算核心密度估计的最近邻居时遇到了它。这个Wikipedia page解释了树的基本定义,John Langford's page有一个指向C ++实现的链接。
单个查询的运行时间为O(c ^ 12 * logn),其中c是数据集的扩展常量。这是一个上限 - 实际上,数据结构的执行速度比其他结构快。 This paper表明,粒子模拟所需的所有最近邻居(对于所有数据点)的批处理运行时间为O(c ^ 16 * n),这个理论线性界限也是实用的为了你的需要。施工时间为O(nlogn),储存为O(n)。