我正在使用KD-Tree优化一组2D点(x,y)上的范围搜索。为了节省时间,我尝试使用 * Java Topology Suite的KD-Tree *。但是,javadoc声明:请注意,KD树的结构取决于插入点的顺序。如果插入点是一致的(例如,在一维或二维中单调),则树可能变得不平衡。完全平衡的树的深度只有log2(N),但不平衡的树可能更深。这对查询效率有严重影响所以我的问题是:如何以最小化树的高度的方式将点插入到 * KD树 * 中?
(x,y)
tjvv9vkg1#
In不会太担心这个问题,这有点像哈希Map,如果所有条目都必须使用相同的哈希码,那么理论上最坏的情况是**O(n)**查找,但实际上这不太可能发生,除非哈希函数有问题。为了避免不平衡,你应该确保你的点数没有以任何方式排列。如果它们是,考虑在插入它们之前打乱它们。另外,一些kd-tree实现有一个rebalance()函数,可以在插入(大量)数据后调用,这将在内部重新平衡树。最后,如果你真的想使用一个特定的插入顺序来避免不平衡,你可以做以下的事情。注意,这个方法不是最优的,它可以避免最坏的情况,但通常不会产生一个完全平衡的树:按x坐标对点排序,然后使用二进制拆分搜索将其插入。例如,如果有15个点,则按'x'对它们排序以获得点p0...p14的排序列表。然后:1.取范围(p7)的中点并插入。1.为拆分点的每一侧创建一个新范围:p0-p6和p8-p151.从1)两个范围中的每一个开始这将产生以下插入顺序:1.圆形:p71.轮次:p3和p111.轮次:p1、p5、p9、p131.四舍五入:p0、p2、p4、p6、p8、p10、p12、p14为什么这不理想?
rebalance()
1条答案
按热度按时间tjvv9vkg1#
In不会太担心这个问题,这有点像哈希Map,如果所有条目都必须使用相同的哈希码,那么理论上最坏的情况是**O(n)**查找,但实际上这不太可能发生,除非哈希函数有问题。
为了避免不平衡,你应该确保你的点数没有以任何方式排列。如果它们是,考虑在插入它们之前打乱它们。
另外,一些kd-tree实现有一个
rebalance()
函数,可以在插入(大量)数据后调用,这将在内部重新平衡树。最后,如果你真的想使用一个特定的插入顺序来避免不平衡,你可以做以下的事情。注意,这个方法不是最优的,它可以避免最坏的情况,但通常不会产生一个完全平衡的树:按x坐标对点排序,然后使用二进制拆分搜索将其插入。例如,如果有15个点,则按'x'对它们排序以获得点p0...p14的排序列表。然后:
1.取范围(p7)的中点并插入。
1.为拆分点的每一侧创建一个新范围:p0-p6和p8-p15
1.从1)两个范围中的每一个开始
这将产生以下插入顺序:
1.圆形:p7
1.轮次:p3和p11
1.轮次:p1、p5、p9、p13
1.四舍五入:p0、p2、p4、p6、p8、p10、p12、p14
为什么这不理想?