OSDN Git Service

Update k-dtree.md
author雷蒻 <34390285+hsfzLZH1@users.noreply.github.com>
Sun, 28 Jul 2019 07:12:00 +0000 (15:12 +0800)
committerGitHub <noreply@github.com>
Sun, 28 Jul 2019 07:12:00 +0000 (15:12 +0800)
docs/ds/k-dtree.md

index b883262..7d377e4 100644 (file)
@@ -20,16 +20,44 @@ k-D Tree 具有二叉搜索树的形态,二叉搜索树上的每个结点都
 
 4.  将选择的点作为这棵子树的根节点,递归对分出的两个超长方体构建左右子树,维护子树的信息。
 
+为了方便理解,我们举一个 $k=2$ 时的例子。
+
+![](./images/kdt1.jpg)
+
+其构建出 k-D Tree 的形态可能是这样的:
+
+![](./images/kdt2.jpg)
+
+其中树上每个结点上的坐标是选择的分割点的坐标,非叶子结点旁的 $x$ 或 $y$ 是选择的切割维度。
+
 这样的复杂度无法保证。对于 $2,3$ 两步,我们提出两个优化:
 
 1.  选择的维度要满足其内部点的分布的差异度最大,即每次选择的切割维度是方差最大的维度。
 
 2.  每次在维度上选择切割点时选择该维度上的 **中位数** ,这样可以保证每次分成的左右子树大小尽量相等。
 
\8f¯ä»¥å\8f\91ç\8e°ï¼\8c使ç\94¨ä¼\98å\8c\96 $2$ å\90\8eï¼\8cæ\9e\84建å\87ºç\9a\84 k-D Tree ç\9a\84深度最多为 $O(\log_2 n)$ 。
\8f¯ä»¥å\8f\91ç\8e°ï¼\8c使ç\94¨ä¼\98å\8c\96 $2$ å\90\8eï¼\8cæ\9e\84建å\87ºç\9a\84 k-D Tree ç\9a\84æ \91é«\98最多为 $O(\log_2 n)$ 。
 
 现在,构建 k-D Tree 时间复杂度的瓶颈在于快速选出一个维度上的中位数,并将在该维度上的值小于该中位数的置于中位数的左边,其余置于右边。如果每次都使用 `sort` 函数对该维度进行排序,时间复杂度是 $O(n\log_2^2 n)$ 的。事实上,单次找出 $n$ 个元素中的中位数并将中位数置于排序后正确的位置的复杂度可以达到 $O(n)$ 。
 
 我们来回顾一下快速排序的思想。每次我们选出一个数,将小于该数的置于该数的左边,大于该数的置于该数的右边,保证该数在排好序后正确的位置上,然后递归排序左侧和右侧的值。这样的期望复杂度是 $O(n\log_2 n)$ 的。但是由于 k-D Tree 只要求要中位数在排序后正确的位置上,所以我们只需要递归排序包含中位数的 **一侧** 。可以证明,这样的期望复杂度是 $O(n)$ 的。在 `algorithm` 库中,有一个实现相同功能的函数 `nth_element()` ,要找到 `s[l]` 和 `s[r]` 之间的值按照排序规则 `cmp` 排序后在 `s[mid]` 位置上的值,并保证 `s[mid]` 左边的值小于 `s[mid]` ,右边的值大于 `s[mid]` ,只需写 `nth_element(s+l,s+mid,s+r+1,cmp)` 。
 
 借助这种思想,构建 k-D Tree 时间复杂度是 $O(n\log_2 n)$ 的。
+
+## 插入/删除
+
+如果维护的这个 $k$ 维点集是可变的,即可能会插入或删除一些点,此时 k-D Tree 的平衡性无法保证。由于 k-D Tree 的构造,不能支持旋转,类似与 FHQ Treap 的随机优先级也不能保证其复杂度,可以保证平衡性的手段只有类似于 [替罪羊树](/ds/scapegoat) 的重构思想。
+
+我们引入一个重构常数 $\alpha$ ,对于 k-D Tree 上的一个结点 $x$ ,若其有一个子树的结点数在以 $x$ 为根的子树的结点数中的占比大于 $\alpha$ ,则认为以 $x$ 为根的子树是不平衡的,需要重构。重构时,先遍历子树求出一个序列,然后用以上描述的方法建出一棵 k-D Tree ,代替原来不平衡的子树。
+
+在插入一个 $k$ 维点时,先根据记录的分割维度和分割点判断应该继续插入到左子树还是右子树,如果到达了空结点,新建一个结点代替这个空结点。成功插入结点后回溯插入的过程,维护结点的信息,如果发现当前的子树不平衡,则重构当前子树。
+
+如果还有删除操作,则使用 **惰性删除** ,即删除一个结点时打上删除标记,而保留其在 k-D Tree 上的位置。如果这样写,当未删除的结点数在以 $x$ 为根的子树中的占比小于 $\alpha$ 时,同样认为这个子树是不平衡的,需要重构。
+
+类似于替罪羊树,带重构的 k-D Tree 的树高仍然是 $O(\log_2 n)$ 的。
+
+## 邻域查询
+
+## 高维空间上的操作
+
+## 习题