简体   繁体   English

如何在AVL树中找到最大值(而不是键)?

[英]How to find max value(not key) in an AVL tree?

I build a simple AVL tree as following, each node has key and value. 我构建了一个简单的AVL树,如下所示,每个节点都有键和值。 Now I want to implement a method that could return the key of node which has the largest value. 现在我想实现一个方法,它可以返回具有最大值的节点的键。 For example, if I have a tree like: 例如,如果我有一个像这样的树:

               (7,1)
             /       \
        (4,3)       (13,8)
        /  \       /      \
    (2,4) (6,3) (11,8)      (15,2)
     / \   /      /  \      /     \
(1,9)(3,0)(5,16)(9,2)(12,3)(14,3)(16,5)
                 / \
              (8,19)(10,4)

The method would return 8, as the node (8,19) has the largest value. 该方法将返回8,因为节点(8,19)具有最大值。 Following is my avl tree and node constructor. 以下是我的avl树和节点构造函数。 I do try to implement this method by hand but somehow it doesn't work. 我尝试手动实现此方法,但不知何故它不起作用。 I'd be grateful if someone coule help me. 如果有人帮助我,我将不胜感激。

public class AVLTreeImp<T extends Comparable<? super T>,V> implements AVLTree<T,V>{
    private Node<T, V> root;
    public class Node<T extends Comparable<? super T>,V> implements AVLTree.Node{
        T key;
        V value;
        Node<T,V> left;
        Node<T,V> right;
        Node<T,V> parent;
        int height;
        public Node(){
            this.key = null;
            this.left = null;
            this.right = null;
            this.parent = null;
            this.height = 0;
            this.value = null;
        }
        public Node(T key, V value, Node<T,V> left, Node<T,V> right){
            this.key = key;
            this.left = left;
            this.right = right;
            this.parent = null;
            this.height = 0;
            this.value = value;
        }
    }

    public AVLTreeImp(){
        this.root = null;
    }
@Override
    public void insert(T key, V value){
        root = insert(root,key,value);

    }
    private Node<T,V> insert(Node<T,V> node, T key, V value){
        if (node == null){
            node = new Node<T,V>(key, value,null,null);
        }else{
            if (key.compareTo(node.key) < 0){
                node.left = insert(node.left, key, value);
                if (!(isBalanced(node))) {
                    if (key.compareTo(node.left.key) < 0) {
                        node = leftLeftRotation(node);
                    } else {
                        node = leftRightRotation(node);
                    }
                }
            }else if (key.compareTo(node.key) > 0){
                node.right = insert(node.right,key,value);
                if (!(isBalanced(node))){
                    if (key.compareTo(node.right.key) > 0){
                        node = rightRightRotation(node);
                    }else{
                        node = rightLeftRotation(node);
                    }
                }
            }
        }
        regenerateHeight(node);
        return node;
    }

Below is my implementation of this method, I'm not sure what's wrong with this. 下面是我对这个方法的实现,我不确定这个有什么问题。

public Integer findMax(){
        Node<Integer,Integer> result = (Node<Integer,Integer>)root;
        result.value = 0;
        return findMax((Node<Integer, Integer>) root,result);
    }
    private Integer findMax(Node<Integer,Integer> node,Node<Integer,Integer> result){
        if (node == null){
            return result.key;
        }
        if (node.value > result.value || 
                (node.value == result.value && node.key.compareTo(result.key) < 0)){
            result = node;
        }
        findMax(node.left,result);
        findMax(node.right,result);
        return result.key;
    }

You have a balanced BST! 你有一个平衡的BST! That means operations like the following are efficient, 这意味着以下操作是有效的,

  1. Insert/Remove 插入/删除
  2. Max/Min key 最大/最小键
  3. Membership Query 会员查询

But turns out, as comment suggested, you'd have to traverse the entire tree to find an element matching your criteria, which is a O(N) op, not optimal. 但事实证明,正如评论建议的那样,你必须遍历整个树才能找到符合你标准的元素,这是一个O(N)op,不是最优的。 Worse, your structure is recursive! 更糟糕的是,你的结构是递归的!

You can, 您可以,

  1. Maintain a priority queue keyed by your “value” 维护一个由您的“价值”键入的优先级队列
  2. Build another tree keyed by your “value” 用你的“价值”建立另一棵树

They are both far more efficient than a full tree look up. 它们比完整的树查找效率更高。

However, without further context, I find you usage of the tree questionable? 但是,没有进一步的上下文,我发现你对树的使用有问题吗? Why is your tree keyed by something you're not operating on? 为什么你的树被你没有操作的东西锁定?

Your recursive findMax method is incorrect. 您的递归findMax方法不正确。 You are assigning result = node; 您正在分配result = node; but this is only local assignment not updating result when calling findMax(node.left,result); 但这只是在调用findMax(node.left,result);时没有更新结果的本地赋值findMax(node.left,result); and findMax(node.right,result); findMax(node.right,result); . This should work: 这应该工作:

public Integer findMax(){
    Node<Integer,Integer> result = (Node<Integer,Integer>)root;
    result = findMax((Node<Integer, Integer>) root,result);
    return result.key;
}

private Node<Integer,Integer> findMax(Node<Integer,Integer> node,Node<Integer,Integer> result){
    if (node == null){
        return result;
    }
    if (node.value > result.value || 
            (node.value == result.value && node.key.compareTo(result.key) < 0)){
        result = node;
    }
    result = findMax(node.left,result);
    result = findMax(node.right,result);
    return result;
}

More about passing java parameters here Is Java "pass-by-reference" or "pass-by-value"? 关于在这里传递java参数的更多信息是Java“pass-by-reference”还是“pass-by-value”?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM