让我们假设节点结构看起来像这样(Java)。
class Node {
Node left;
Node right;
int key;
int value;
int tree_max;
}
tree_max 的重复频率是
node.tree_max == max(node.value, node.left.tree_max, node.right.tree_max),
当node.left 为空时,由于滥用符号,我们省略了node.left.tree_max,而当node.right 为空时,我们省略了node.right.tree_max。每次我们写入一个节点时,我们可能必须更新它的所有祖先。我不会写伪代码,因为没有编译器我很可能会出错。
为了找到键 k1 和 k2 之间的最大值,我们首先找到这些节点的最小共同祖先。
Node lca = root;
while (lca != null) {
if (lca.key < k1) { lca = lca.left; }
else if (k2 < lca.key) { lca = lca.right; }
else { break; }
}
现在,如果lca 为空,则范围为空,我们应该返回负无穷大或抛出异常。否则,我们需要找到三个范围内的最大值: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; }
}