繁体   English   中英

AVL树平衡

[英]AVL Tree Balancing

我正在进行一项任务,要求我实现一个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))时间,它可以正常旋转。

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

你的代码正在攀升你走下去的路径。 考虑以下代码:

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

并稍微修改它:

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

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

更新最新代码

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

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

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

暂无
暂无

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

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