【问题标题】:AVL Tree: Finding the key with the smallest data values in keys between two values in O(logn) timeAVL 树:在 O(logn) 时间内找到两个值之间的键中数据值最小的键
【发布时间】:2014-10-07 23:08:21
【问题描述】:

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

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

【问题讨论】:

    标签: algorithm pseudocode avl-tree


    【解决方案1】:

    让我们假设节点结构看起来像这样(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。每次我们写入一个节点时,我们可能必须更新它的所有祖先。我不会写伪代码,因为没有编译器我很可能会出错。

    为了找到键 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 为空,则范围为空,我们应该返回负无穷大或抛出异常。否则,我们需要找到三个范围内的最大值: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; }
    }
    

    【讨论】:

    • 既然我说我试图找到最小值而不是最大值,除了找到最小值相反之外,它基本上与此相同?
    • @MangoOfFury 哎呀,是的。
    猜你喜欢
    • 2013-09-12
    • 2012-09-02
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 2019-06-11
    • 2020-06-08
    相关资源
    最近更新 更多