重点:kd-tree 和 range tree
首先,可以参考 ass2 的第一题,kd-tree 的绘制和 range-tree 的绘制。
其次,我们来一点点深入了解这几个知识点。
# kd-tree
kd-tree 在后续的许多应用中都会有涉及。
首先,构建 kd-tree 需要 O (nlogn) 的构建时间和 O (n) 的构建空间 (具体推导过程可以去看 ppt)
🔹 方案一:使用排序方式找中位数
在每一层:
- 排序或选择中位点: O (n) 或 O (nlogn),具体取决于用排序还是选择算法。
- 划分左右子树: O(n)
- 递归调用左右子树: 每边是 n/2 个点
于是:
这就是典型的完全二叉树构建递归式,解出来是:
以及标准的平衡二叉树空间复杂度 O (n)
然后是查询的时间复杂度
查询时间分析核心思想
我们想知道:有多少个 “被访问但不产生结果” 的节点?(即这些节点的 region 与 R 相交,但最终不包含任何点)
老师采用的是可视化 + 递归建模来分析。
- 假设我们用一条竖线 L 穿过查询矩形 R;
- 然后问:有多少个 KD-Tree 划分出来的矩形 region 会跟这条 L 相交?
结论:
这个数量最多是 ,再乘上一个常数(最多 4 个区域被每个水平或垂直线段交到)。
定义 Q (n):查询一个 KD-Tree 有 nnn 个点时最多访问的节点数。
- 第一层我们访问 1 个节点;
- 第二层我们可能访问它的两个子树(假设是四个区域);
- 然后分别继续查各自的左右子树。
于是得:
✅ 五、最终查询时间总结(第 6 张图)
你可以记住这句最核心的 KD-Tree 查询时间分析结论:
其中:
- :是最多访问这么多个 “无用节点” 的上界;
- k:是最终在矩形 R 中找到的点的个数(输出代价)。
# range-tree
通俗来讲,就是把树按照 x 来排列,然后在每个子节点的上面挂一个子树,存放着 y 坐标
但是因此时间复杂度较高,因为两个树进行二分查找的时间复杂度都为 O (logn),因此,总的复杂度需要 O (logn) * O (logn) =
那么有什么优化的方式吗?
Fractional Cascading
将 Range Tree 的子树部分切割成指针引导的结构,即可以 把子树的二分查找的优化掉。