为什么我的Java中的AVL树存在节点问题?

时间:2014-02-20 04:02:04

标签: java tree

我正在开发的当前项目是开发一个AVL树类。我不是最优秀的程序员,但我确实很清楚这个结构应该如何工作。我的第一个测试案例是RL不平衡,我的树能够正确重组。然而,对于我的LL失衡的下一个测试案例,发生了一些奇怪的事情。我的代码正确地识别了不平衡,它似乎正确地旋转,但是对于最终树,在平衡之前添加的节点被移除并且树恢复到添加节点之前的状态。解释这有点奇怪的问题当然我会提供我的代码。完全有可能我只是在某个地方犯了一个愚蠢的错误,但那些新鲜的眼睛真的会有所帮助。此外,如果有人有任何建议,以改善我的编码实践,将不胜感激,谢谢!

这个类是我为我的课程开发的数据结构库的一部分。我将仅发布此类的代码,但如果有人需要接口/超类,我可以提供它们。

package lib280.tree;

public class AVLTree280<I extends Comparable<? super I>> extends OrderedSimpleTree280<I>{



protected AVLNode280<I> AVLNode280RootLeftChild(){
    return (AVLNode280<I>) this.rootNode().leftNode();
}

protected AVLNode280<I> AVLNode280Root(){
    return (AVLNode280<I>) this.rootNode();
}

protected AVLNode280<I> AVLNode280RootRightChild(){
    return (AVLNode280<I>) this.rootNode().rightNode();
}

protected AVLNode280<I> createNewNode(I x){
    return new AVLNode280<I>(x);
}

public AVLTree280<I> rootLeftSubtree(){
    return (AVLTree280<I>) super.rootLeftSubtree();
}

public AVLTree280<I> rootRightSubtree(){
    return (AVLTree280<I>) super.rootRightSubtree();
}



/** Insert x into the tree. <br>
Analysis : Time = O(log n) worst case, where **/
public void insert(I x,AVLTree280<I> tree)
{
    if (tree.isEmpty()){
        tree.rootNode = createNewNode(x);
    }
    else if (x.compareTo(tree.rootItem()) < 0)
    {
        if(tree.rootNode().leftNode()==null) tree.rootNode().leftNode=createNewNode(x);

        else{
            insert(x,tree.rootLeftSubtree());
        }

        tree.AVLNode280Root().setLeftSubTreeHeight((Math.max(tree.AVLNode280RootLeftChild().getRightSubTreeHeight(), tree.AVLNode280RootLeftChild().getLeftSubTreeHeight()))+1);

    }

    else{

        if(tree.rootNode().rightNode()==null) tree.rootNode().rightNode=createNewNode(x);

        else{
            insert(x,tree.rootRightSubtree());
        }

        tree.AVLNode280Root().setRightSubTreeHeight((Math.max(tree.AVLNode280RootRightChild().getLeftSubTreeHeight(), tree.AVLNode280RootRightChild().getRightSubTreeHeight()))+1);
    }

    restoreAVLProperty(tree);
}


protected int balancingFactor(AVLTree280<I> tree){
    return tree.AVLNode280Root().getLeftSubTreeHeight()-tree.AVLNode280Root().getRightSubTreeHeight();
}


protected void restoreAVLProperty(AVLTree280<I> tree){
    if (balancingFactor(tree) == 2) { //left side
        if (balancingFactor(tree.rootLeftSubtree()) == -1) { //reduce left right imbalance to left left
            tree.rootNode().leftNode=rotateLeft(tree.AVLNode280RootLeftChild());
        }

        tree.rootNode=rotateRight(tree.AVLNode280Root());// fix left left imbalance
        System.out.println("The tree root node at this point is: " +tree.rootNode().toString());
    } 
    else if(balancingFactor(tree)==-2){ // right side
        if (balancingFactor(tree.rootRightSubtree()) == 1) { //reduce right left imbalance to right right
                    tree.rootNode().rightNode=rotateRight(tree.AVLNode280RootRightChild()); 
                }

        tree.rootNode=rotateLeft(tree.AVLNode280Root()); //fix right right imbalance
    }
    else{

    }
}

protected AVLNode280<I> rotateLeft(AVLNode280<I> node){
    AVLNode280<I> holder,holder2;
    holder=(AVLNode280<I>) node.rightNode();
    node.setRightNode(holder.leftNode());
    holder.setLeftNode(node);

    holder2 = (AVLNode280<I>) node.rightNode();
    if(holder2!=null){
        node.setRightSubTreeHeight(Math.max(holder2.getLeftSubTreeHeight(),holder2.getRightSubTreeHeight())+1);
    }
    else{
        node.setRightSubTreeHeight(0);
    }

    holder2 = (AVLNode280<I>) node.leftNode();
    if(holder2!=null){
        node.setLeftSubTreeHeight(Math.max(holder2.getLeftSubTreeHeight(),holder2.getRightSubTreeHeight())+1);
    }
    else{
        node.setLeftSubTreeHeight(0);
    }

    holder2=(AVLNode280<I>) holder.rightNode();
    if(holder2!=null){
        holder.setRightSubTreeHeight(Math.max(holder2.getLeftSubTreeHeight(),holder2.getRightSubTreeHeight())+1);
    }
    else{
        holder.setRightSubTreeHeight(0);
    }

    holder.setLeftSubTreeHeight(Math.max(node.getLeftSubTreeHeight(),node.getRightSubTreeHeight())+1);

    return holder;
} 

protected AVLNode280<I> rotateRight(AVLNode280<I> node){
    AVLNode280<I> holder,holder2;
    holder=(AVLNode280<I>) node.leftNode();
    node.setLeftNode(holder.rightNode());
    holder.setRightNode(node);

    holder2 = (AVLNode280<I>) node.leftNode();
    if(holder2!=null){
        node.setLeftSubTreeHeight(Math.max(holder2.getLeftSubTreeHeight(),holder2.getRightSubTreeHeight())+1);
    }
    else{
        node.setLeftSubTreeHeight(0);
    }

    holder2 = (AVLNode280<I>) node.rightNode();
    if(holder2!=null){
        node.setRightSubTreeHeight(Math.max(holder2.getLeftSubTreeHeight(),holder2.getRightSubTreeHeight())+1);
    }
    else{
        node.setRightSubTreeHeight(0);
    }

    holder2=(AVLNode280<I>) holder.leftNode();
    if(holder2!=null){
        holder.setLeftSubTreeHeight(Math.max(holder2.getLeftSubTreeHeight(),holder2.getRightSubTreeHeight())+1);}
    else{
        holder.setLeftSubTreeHeight(0);
    }

    holder2=(AVLNode280<I>) holder.rightNode();
    if(holder2!=null){
    holder.setRightSubTreeHeight(Math.max(node.getLeftSubTreeHeight(),node.getRightSubTreeHeight())+1);
    }
    else{
        holder.setRightSubTreeHeight(0);
    }

    System.out.println("Holder at this point is: " +holder.toString());
    return holder;
}

public void printTreeHeights(AVLNode280<I> node){
    if(node==null) return;
    System.out.println("left: "+ Integer.toString(node.getLeftSubTreeHeight())+" , "+ "right: "+ Integer.toString(node.getRightSubTreeHeight())+"\n");
    printTreeHeights((AVLNode280<I>)node.leftNode());
    printTreeHeights((AVLNode280<I>)node.rightNode());
        }


/**
 * @param args
 */
public static void main(String[] args) {
    AVLTree280<Integer> testAVL=new AVLTree280<Integer>();

    System.out.println("Test for RL imbalance");
    testAVL.insert(5, testAVL);
    //System.out.println(testAVL.toString());
    testAVL.insert(10, testAVL);
//  System.out.println(testAVL.toString());
    testAVL.insert(6,testAVL);
    //System.out.println(testAVL.toString());
//  testAVL.printTreeHeights(testAVL.AVLNode280Root());
    System.out.println("-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-");

    System.out.println("Test for LL imbalance");
    testAVL.insert(1,testAVL);
    System.out.println(testAVL.toString());
    //testAVL.printTreeHeights(testAVL.AVLNode280Root());
    testAVL.insert(0,testAVL);
    //testAVL.printTreeHeights(testAVL.AVLNode280Root());
    System.out.println(testAVL.toString());
}

}

具有级别顺序遍历的第一种情况的输出是6,5,10

下一个案例使用级别顺序遍历为6,5,10,1。插入0并重新平衡后,树会回到6,5,10。这很奇怪,因为我有一个语句打印重新平衡后要返回的值

此时持有人是:1 此时树根节点为:1

这两个陈述表明LL重新平衡发生但没有正确更新。

0 个答案:

没有答案