【KD树】 学习资料(转自木子日匀大神)
2014-06-29 20:48
169 查看
KD树是一种能在O(nlog(n))时间内把平面划分成若干个区域,然后在均摊O(n√+k)的时间内找到某个区域内所有点的数据结构。
其思想是,每次把当前处理的区域按照点数分成两部分,然后对两部分进行递归处理。。。
分成两部分有两种策略,一种是横着竖着横着竖着交替划分。。
一种是把坐标跨度大的那一维划分成两部分。
似乎没什么影响。
上图是一种可行的划分方式。每次找到当前处理点集[L,R]中的中点mid,以这个中点为分界线把区间划分成两部分[L,mid−1]和[mid+1,R]。注意中点是作为分界线不参与下一轮处理。(我写法是这样的)。
查询一个点的最近点时,首先令最近距离为∞,然后在KD树中查找,首先和当前区间的中点求一次距离更新答案,然后再根据该点和中点的关系决定是去左区间还是右区间,如果正好在分界线上那么两边都过去吧。
这里还有个问题,可能点被分到了左区间,但是可能和右区间的某个点比较近。那么怎么办。?
假设这个点到分界线的距离已经是大于等于当前最优答案了,那么另一个区间的所有点到这个点的距离都比当前最优答案远,只有这时候不需要考虑另一个区间。
这个看起来蠢爆了好么。但是复杂度分析均摊下来的确是O(n√+k),详情可以参观一下《计算几何:算法与应用》那本书。
STL中提供了一个叫做nth_element的函数,可以在O(n)的复杂度下找到序列的第k大数并且把序列以第k大为界分为两半,用这个就能写出很短的建树过程了。
?
代码君
查找的时候照着思路写就可以了。
?
代码君
这份KD树是参照佐倉杏子的代码学习的。Orz。
相关题目:In case of failure
别的用处。。?何老鱼说可以维护一个矩形区域的点的权值和啊之类的问题。还没细想。
其思想是,每次把当前处理的区域按照点数分成两部分,然后对两部分进行递归处理。。。
分成两部分有两种策略,一种是横着竖着横着竖着交替划分。。
一种是把坐标跨度大的那一维划分成两部分。
似乎没什么影响。
上图是一种可行的划分方式。每次找到当前处理点集[L,R]中的中点mid,以这个中点为分界线把区间划分成两部分[L,mid−1]和[mid+1,R]。注意中点是作为分界线不参与下一轮处理。(我写法是这样的)。
查询一个点的最近点时,首先令最近距离为∞,然后在KD树中查找,首先和当前区间的中点求一次距离更新答案,然后再根据该点和中点的关系决定是去左区间还是右区间,如果正好在分界线上那么两边都过去吧。
这里还有个问题,可能点被分到了左区间,但是可能和右区间的某个点比较近。那么怎么办。?
假设这个点到分界线的距离已经是大于等于当前最优答案了,那么另一个区间的所有点到这个点的距离都比当前最优答案远,只有这时候不需要考虑另一个区间。
这个看起来蠢爆了好么。但是复杂度分析均摊下来的确是O(n√+k),详情可以参观一下《计算几何:算法与应用》那本书。
STL中提供了一个叫做nth_element的函数,可以在O(n)的复杂度下找到序列的第k大数并且把序列以第k大为界分为两半,用这个就能写出很短的建树过程了。
?
?
相关题目:In case of failure
别的用处。。?何老鱼说可以维护一个矩形区域的点的权值和啊之类的问题。还没细想。
相关文章推荐
- python中的字符编码和解码学习记录-0627,大神请帮忙提供系统资料
- 【AC自动机模板】(转自木子日匀大神)
- Openstack学习资料链接总结(包括主要的大神级博客)
- VC学习资料收集(6):连连看通路检测算法
- 绝对经典英语学习资料
- VC学习资料收集(4):设计XP风格的按钮
- VC学习资料收集(2):关于数据类型转换
- 绝对经典英语学习资料
- 学习htc文件的相关中文资料
- VC学习资料收集(10):udp服务器设计过程总结
- VC学习资料收集(8):用Visual C++操作INI文件
- OpenGL D3D 学习资料
- VC学习资料收集(13):单独使用CRecordSet
- VC学习资料收集(18):VC ++ 如何取出系统时间
- VC学习资料收集(12):VC小知识总结
- Python学习资料(1):Think in Python
- VB.NET学习资料:
- C#学习资料和网址
- VC学习资料收集(7):关于《连连看》的算法
- VC学习资料收集(17):实战VC时间控制函数