我们假设节点结构如下所示(Java)。
class Node {
Node left;
Node right;
int key;
int value;
int tree_max;
}
复发为tree_max
is
node.tree_max == max(node.value, node.left.tree_max, node.right.tree_max),
由于滥用符号,我们省略了node.left.tree_max
when node.left
为空并省略node.right.tree_max
when node.right
一片空白。每次我们写入一个节点时,我们可能都必须更新它的所有祖先。我不会编写伪代码,因为如果没有编译器,我很可能会出错。
查找键之间的最大值k1
and k2
包含在内,我们首先找到这些节点的最不共同的祖先。
Node lca = root;
while (lca != null) {
if (lca.key < k1) { lca = lca.left; }
else if (k2 < lca.key) { lca = lca.right; }
else { break; }
}
Now, if lca
为 null,则范围为空,我们应该返回负无穷大或抛出异常。否则,我们需要找到三个范围内的最大值:k1
包含于lca
独家的,lca
本身,以及lca
专属于k2
包括的。我将给出代码k1
包含于lca
独家的;其他两个范围分别是平凡的和对称的。我们走finger
就好像我们在寻找一样从树上下来k1
,将最大值累加到left_max
.
int left_max = /* minus infinity */;
Node finger = lca.left;
while (finger != null) {
if (k1 <= finger.key) {
left_max = max(left_max, finger.value);
if (finger.right != null) { left_max = max(left_max, finger.right.tree_max); }
finger = finger.left;
} else { finger = finger.right; }
}