zoukankan      html  css  js  c++  java
  • K-D Tree 学习笔记

    又是一个不需要证明的东西,复杂度基本玄学。
    具体来说 K-D Tree 是解决高维问题的一个数据结构(其实一般是二维)。
    K-D Tree 本质上是一棵二叉搜索树,其的基本思想就是遍历整个状态空间加剪枝。
    设问题维度是K,其单次查询的复杂度大概是 (O(n^{frac{K-1}{K}}))

    K-D Tree 的建树方法

    我们一般采用每次随机找一个维度,以这个维度排序,且以这个维度的中位数为根的方法。
    这种方法基本上不会被卡。
    一般来说我们维度的选择就是从 1-K 反复循环进行的。

    K-D Tree 的查询方法

    这个就具体问题具体分析了,说几个经典问题吧。

    最远点

    找距离一个坐标最远的点。
    这个比较简单,维护每颗子树里每一维最大和最小的值,然后一一配对取最大值就可以了。

    最近点

    这个就比较妙了。
    我们依旧维护每颗子树里每一维最大和最小的值;
    然后对于每一维我们找到理想状态下距离最近的点,加入答案中。
    其实本质上是 A*。
    算了,给个代码实现吧。

    int getmin(int rt, int x, int y, int res = 0) {
        for(register int i = 0; i < 2; ++i) {
    	    if(i == 1) x = y;
    	    res += max(0, tr[rt].mi[i] - x);
    	    res += max(0, x - tr[rt].mx[i]);
    	}
        return res; 
    }
    

    K远点

    一般来说 K 不会很大。
    这个我们可以开个小根堆,初始时堆里有 K 个元素。
    查询时每次替换最小的那个就可以了。

    动态插入

    主要利用的是替罪羊的思想。
    插入的话我们直接向平衡树那样插入就可以了。
    维护平衡因子,适时推翻重建以维护平衡。
    (暂时没有写过)

  • 相关阅读:
    CPU使用率呈现正弦曲线
    编写一个简单的http server(Linux, gcc)
    c#操作 文件操作
    Javascript 数字时钟
    .net 中读取文本文件
    c# 常用字符串函数
    I2C总线之(三)以C语言理解IIC
    典型的多线程操作界面的例子
    uvm_common_phase.svh
    uvm_task_phase.svh
  • 原文地址:https://www.cnblogs.com/longdie/p/K-DTree.html
Copyright © 2011-2022 走看看