小编典典

AVL树:在O(logn)时间的两个值之间找到键中数据值最小的键

algorithm

因此,我得到了AVL树。我试图找出至少伪代码,以找到两个值k1和k2之间的所有密钥中具有最小数据值的密钥。假设存储在每个节点中的字段数据是整数。我想确保我的伪代码在O(logn)时间运行。

我知道我可以通过在节点结构中存储一个额外的字段来做到这一点,并显示在更新过程中如何维护该字段,但是我不知道从那里去哪里。


阅读 349

收藏
2020-07-28

共1个答案

小编典典

假设节点结构看起来像这样(Java)。

class Node {
    Node left;
    Node right;
    int key;
    int value;
    int tree_max;
}

复发的tree_maxIS

node.tree_max == max(node.value, node.left.tree_max, node.right.tree_max),

通过滥用符号,我们忽略node.left.tree_maxwhen
node.left为null并省略node.right.tree_maxwhen
node.right为null。每次我们写入节点时,可能都必须更新其所有祖先。我不会编写伪代码,因为如果没有编译器,我很可能会弄错它。

为了找到键k1k2包含键之间的最大值,我们首先找到那些节点的最小公共祖先。

Node lca = root;
while (lca != null) {
    if (lca.key < k1) { lca = lca.left; }
    else if (k2 < lca.key) { lca = lca.right; }
    else { break; }
}

现在,如果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; }
}
2020-07-28