OSDN Git Service

style: format markdown files with remark-lint
author24OI-bot <15963390+24OI-bot@users.noreply.github.com>
Sun, 28 Jul 2019 06:00:19 +0000 (02:00 -0400)
committer24OI-bot <15963390+24OI-bot@users.noreply.github.com>
Sun, 28 Jul 2019 06:00:19 +0000 (02:00 -0400)
docs/ds/k-dtree.md

index 43ba83d..f841487 100644 (file)
@@ -8,21 +8,21 @@ k-D Tree(k-Dimension Tree) 是一种可以 **高效处理 $k$ 维空间信息**
 
 k-D Tree 具有二叉搜索树的形态,二叉搜索树上的每个结点都对应 $k$ 维空间内的一个点。其每个子树中的点都在一个 $k$ 维的超长方体内,这个超长方体内的所有点也都在这个子树中。
 
-假设我们已经知道了 $k$ 维空间内的 $n$ 个不同的点的坐标,要将其构建成一棵 k-D Tree ,步骤如下:
+假设我们已经知道了 $k$ 维空间内的 $n$ 个不同的点的坐标,要将其构建成一棵 k-D Tree,步骤如下:
 
-1. 若当前超长方体中只有一个点,返回这个点。
+1.  若当前超长方体中只有一个点,返回这个点。
 
-2. 选择一个维度,将当前超长方体按照这个维度分成两个超长方体。
+2.  选择一个维度,将当前超长方体按照这个维度分成两个超长方体。
 
-3. 选择切割点:在选择的维度上选择一个点,这一维度上的值小于这个点的归入一个超长方体(左子树),其余的归入另一个超长方体(右子树)。
+3.  选择切割点:在选择的维度上选择一个点,这一维度上的值小于这个点的归入一个超长方体(左子树),其余的归入另一个超长方体(右子树)。
 
-4. 将选择的点作为这棵子树的根节点,递归对分出的两个超长方体构建左右子树,维护子树的信息。
+4.  将选择的点作为这棵子树的根节点,递归对分出的两个超长方体构建左右子树,维护子树的信息。
 
 这样的复杂度无法保证。对于 $2,3$ 两步,我们提出两个优化:
 
-1. 选择的维度要满足其内部点的分布的差异度最大,即每次选择的切割维度是方差最大的维度。
+1.  选择的维度要满足其内部点的分布的差异度最大,即每次选择的切割维度是方差最大的维度。
 
-2. 每次在维度上选择切割点时选择该维度上的 **中位数** ,这样可以保证每次分成的左右子树大小尽量相等。
+2.  每次在维度上选择切割点时选择该维度上的 **中位数** ,这样可以保证每次分成的左右子树大小尽量相等。
 
 可以发现,使用优化 $2$ 后,构建出的 k-D Tree 的深度最多为 $O(\log_2 n)$ 。
 
@@ -31,4 +31,3 @@ k-D Tree 具有二叉搜索树的形态,二叉搜索树上的每个结点都
 我们来回顾一下快速排序的思想。每次我们选出一个数,将小于该数的置于该数的左边,大于该数的置于该数的右边,保证该数在排好序后正确的位置上,然后递归排序左侧和右侧的值。这样的期望复杂度是 $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)$ 的。
-