KD-Tree

定义

一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。

但是一般用于二维空间。

个人感觉也挺像一棵平衡树的。

构建/插入

可以将所有点存到一个数组里边然后一次性建树,也可每次插入一个点。

先说一次性建树,为了让它显得更加平衡一点也方便查询,要把靠的近的点尽量放到一起,实现的方法有很多,但是实测按照每一维轮换着作为当前层划分的依据是最优的,虽然用方差感觉更靠谱,可能是常数的原因。

每次插入一个点也是考虑这个点与当前节点划分依据的那一维度的比较,小就左子树否则就右子树。

这个也可以做动态插入,就是边询问边修改,或者可以理解为CDQ分治的某种在线替代。

不过要注意的是插入的时候需要判断当前树是否平衡,并且在插入之前判断,不然可能会导致在回溯的时候重构多棵子树。

询问

KD-Tree能够快速处理对于维护点集的询问,这是基于它在插入时对点的划分较为均匀,但是划分的时候也不一定完全均匀,所以对于询问一颗子树的时候不大好搞,但可以通过预处理一些简单的东西得到这棵子树的信息,大概需要得到每一维度的最大值,最小值。

这样就能够基本判断这棵子树的三种情况:

  1. 所有点均在询问范围外
  2. 所有点均在询问范围内
  3. 部分点在询问范围内

对于1,2情况的处理很好办,对于3好像有什么办法,所以直接递归处理。

这样做的时间复杂度也不是很对,还需要加上估价函数。

对于求最大最小的操作,先进入最有可能更新答案的子树搜索,这样有可能另一个子树就不用搜了,时间复杂度为\(O(n^{\frac{k-1}k})\)

但是对于别的操作,时间负责度貌似仍然不是很对,但是能骗到很多分。。

另外还有一些比较高级的操作这篇博客写的挺好

posted @ 2020-12-18 08:34  An_Fly  阅读(106)  评论(1编辑  收藏  举报