我找到的唯一合理的幻灯片集是this,在第15页中说,用于构建:
- 按x坐标值对所有点进行排序并将其存储在 平衡二叉树的叶节点(即范围树)
- 从根开始,每个节点包含其子树中的点,其y坐标的最大值尚未存储
在树的较浅的深度;如果不存在这样的节点,那么节点
是空的
我实现了一个范围树just before,因此根据我在那里使用的示例,我现在(对于优先搜索树):
7
------ 0 ---------------------
| |
6 6
---- -3 ---- ---- 4 ------
| | | |
4 2 1 3
---- -4 - -2 --- 3 --- 5
| | / \ | | / \
0 (-3,4) (-2,2)(0,7) NIL (4,-4) (5,3)(6,-1)
-5 2
/ \ / \
(-5,6) (-4,0) (2,1) (3,6)
此处,每个内部节点的格式为:
mid_x
max y
我正在构建的范围查询是(-inf,1)x(-0.5,5),即(x_low,x_high)x(y_low,y_high)。
在构建/搜索过程中我缺少什么?
换句话说:
检查树的最左边的分支;它有max_y
个值(引用中的第2个子弹),7,6,4,0。
但该值是否指示存储在内部节点下的子树中的最大y值的值?如果是,则不适用于0
和点(-5, 6)
(6未使用,因为它在第2级使用)。
* 我提出的特定查询可能不会被此损坏,但另一个可以。
答案 0 :(得分:2)
你最后的逻辑实际上仍然是正确的。当您点击标记为(6,-3)的节点时,应该已经拾取了(-5,6)值。 现在,我没有数学专业。但总体思路是这样的。在您实施的优先搜索树中,您实际上是在两个不同的标准上进行搜索。 对于x,它是对范围的简单二进制搜索。 对于y,您实际上正在搜索它作为优先级树(适合搜索y:inf或-inf:y,具体取决于您使用的是max还是min。)
请注意,在第15页的底部,它指出树适用于半无限范围(一个是无限的)。继续阅读,您将看到树如何针对y的半无限范围进行优化。
简而言之,由于您的树构造为x作为二分搜索,y作为优先级(使用最大剩余值),最佳搜索是[x1:x2],[y1:inf]。
树中的每个节点实际上存储了两件事。 1. x的中点(或左树中的max-x,以及向左或向右移动的决定基于> x检查)。 2.子树中y值最高且未添加到前一个的POINT。
搜索算法基本上是这样的。使用[x1:x2],[y1:inf]标准从根开始 1.检查分配给节点的POINT的y值。如果y> y1,转到2,否则STOP遍历(因为分配给节点的POINT具有最高y值,如果检查失败,则其下面没有其他节点可以满足[y1:inf]。 2.检查点的x值是否在[x1:x2]的范围内。如果是这样,请在输出中包含该点。无论您是否包括该点,都继续执行步骤3。 3.检查节点"中点"价值(让我们称之为mx)。如果mx在[x1:x2]的范围内,则向下遍历两个路径。如果mx是< [x1:x2],向左移动。否则就行了。对于您遍历的每条路径,请返回步骤1。
编辑非常非常长的文字: 让我们来看看你的例子吧。我已经使用字母(点" s"名称")标记了每个点的附加注释。每个节点现在都具有点名称的格式,在父母的情况下具有y值,并且"中间范围"它下面的x。对于叶节点,那些带有' *'意味着它们已经被分配到树的某个地方,如果你到达它们,应该被视为NIL。
7(E)
------ 0 ---------------------
| |
A(6) G(6)
----- -3 ----- ---- 4 --------
| | | |
C(4) D(2) F(1) I(3)
---- -4 - -2 --- 3 --- 5
| | / \ | | / \
B(0) C*(-3,4)D*(-2,2)E*(0,7) NIL H(4,-4) I*(5,3)J(6,-1)
-5 2
/ \ / \
A*(-5,6)B*(-4,0) F*(2,1) G*(3,6)
让我们运行[-2:4] [1:inf](或任何y> = 1)的示例查询
结果是" E,F,G"在范围内。