AVL 树平衡

Posted

技术标签:

【中文标题】AVL 树平衡【英文标题】:AVL Tree Balancing 【发布时间】:2010-01-05 05:32:34 【问题描述】:

我正在处理一项要求我实现 AVL 树的任务。我很确定我的轮换方法是正确的,但我无法确定何时使用它们。

例如,书中的解释说我应该爬上与插入节点/元素相同的路径。但是,我不能有任何父指针。

最新代码:

public BinaryNode<T> insert(BinaryNode<T> node) 
    if (this.getElement().compareTo(node.getElement()) > 0) 
        if (this.getLeftChild() != null) 
            BinaryNode<T> b = this.getLeftChild().insert(node);

            if(!this.isBalanced()) 
                this.balance();
            

            return b;
         else 
            this.setLeftChild(node);
        

     else if (this.getElement().compareTo(node.getElement()) < 0) 
        if (this.getRightChild() != null) 
            return this.getRightChild().insert(node);
         else 
            this.setRightChild(node);
        
    

    return this;

我在这里要做的是爬回树上,但它只能在插入节点后检查平衡。因此,这在 else 子句中。

我还尝试将天平代码放在 R Samuel Klatchko 建议的位置,但检查了每个插件上的天平。例如:如果连续插入 7、9、5、3、1,尝试插入 1 时会出现空指针异常。

编辑:上述的一个原因可能与我做高度的方式有关。如果我每次都使用 height() 计算高度,但它会破坏 AVL 树的 O(log(n)) 时间。

关于如何实现这一点的任何想法?

【问题讨论】:

【参考方案1】:

您的代码正在沿着您走下的同一条路径向上爬。考虑这段代码:

if (this.getLeftChild() != null) 
    return this.getLeftChild().insert(node);
 

并稍作修改:

if (this.getLeftChild() != null) 
    boolean b = this.getLeftChild().insert(node);
    // do something here
    return b;
 

当代码从递归调用中返回时,每次返回都会将您带回父级。通过不立即返回递归调用的值,您就有机会进行重新平衡。

更新最新代码

当你插入到右边时不要忘记重新平衡。

【讨论】:

那是我应该放置平衡算法的地方吗?不是在我实际插入节点之后吗?我认为我的困惑来自对这里发生的递归缺乏充分的理解。 所以我尝试了一个类似上面的实现,它在上下时检查余额。有没有办法只在上去的时候检查一下? 请使用您的最新代码更新问题(并添加评论,以便我知道何时查看)。【参考方案2】:

您可以尝试将父指针传递给insert 方法,或者您可以将insert 转换为迭代方法并保留一个显式堆栈,在该堆栈上记录沿树向下的路径。

顺便说一句,为了选择使用哪个旋转,你可以只知道一个节点是不平衡的,你必须知道更深的子树是在右边还是在左边。这意味着您的简单 isBalanced 方法还不够。这也是低效的,并且会破坏 AVL 树的 O(log n) 复杂度,因为您每次都要计算高度。

【讨论】:

是的,我知道身高问题。这是我以后可以解决的小问题。我还计划添加一种方法来判断哪个孩子更高,或者换句话说,它违反了 AVL 平衡属性。 知道如何检测不平衡节点是需要单轮还是双轮旋转? en.wikipedia.org/wiki/AVL_tree 试图概述如何选择旋转。我建议从那里开始,也许在教科书或其他论文中找到对该算法的描述。

以上是关于AVL 树平衡的主要内容,如果未能解决你的问题,请参考以下文章

解密树的平衡:二分搜索树 → AVL自平衡树 → 左倾红黑树

解密树的平衡:二分搜索树 → AVL自平衡树 → 左倾红黑树

树结构实际应用之平衡二叉树(AVL 树)

解密树的平衡:二分搜索树 → AVL自平衡树 → 红黑树

AVL树完美平衡问题

平衡二叉查找树——AVL树