java实现AVL数的插入 递归实现

    AVL树又叫做二叉平衡树,每当我们插入一个节点的时候都要检查该树是否平衡,即在二叉树中是否存在某个节点的左右子树高度的绝对值相差大于1.如果

大于一,则需要分为LL,RR,LR,RL四种情况来分别讨论,但是实际上只需要使用JAVA实现LL,RR这两种类型就行 对于LR,和RL这两种情况只需要分

别重复调用 LL,RR和RR,LL即可

   在这里我们的AVL树的节点定义为

     private static class AvlNode<T>{//avl树节点
        
        AvlNode( T theElement )
        {
            this( theElement, null, null );
        }
        AvlNode( T theElement, AvlNode<T> lt, AvlNode<T> rt )
        {
            element  = theElement;
            left     = lt;
            right    = rt;
            height   = 0;
        }
        T           element;      // 节点中的数据
        AvlNode<T>  left;         // 左儿子
        AvlNode<T>  right;        // 右儿子
        int         height;       // 节点的高度
    }

我们的LL旋转为

   private AvlNode<T> rotateWithLeftChild( AvlNode<T> k2 )
    {
        AvlNode<T> k1 = k2.left;
        k2.left = k1.right;
        k1.right = k2;
        k2.height = Math.max( height( k2.left ), height( k2.right ) ) + 1;
        k1.height = Math.max( height( k1.left ), k2.height ) + 1;
        return k1;
    }

RR旋转为

    private AvlNode<T> rotateWithRightChild( AvlNode<T> k1 )
    {
        AvlNode<T> k2 = k1.right;
        k1.right = k2.left;
        k2.left = k1;
        k1.height = Math.max( height( k1.left ), height( k1.right ) ) + 1;
        k2.height = Math.max( height( k2.right ), k1.height ) + 1;
        return k2;
    }

LR和RL旋转分别为

    private AvlNode<T> doubleWithLeftChild( AvlNode<T> k3 )
    {
        k3.left = rotateWithRightChild( k3.left );
        return rotateWithLeftChild( k3 );
    }

    private AvlNode<T> doubleWithRightChild( AvlNode<T> k1 )
    {
        k1.right = rotateWithLeftChild( k1.right );
        return rotateWithRightChild( k1 );
    }

接下来实现AVL的插入算法

private AvlNode<T> insert( T x, AvlNode<T> t )
    {
        if( t == null )
            return new AvlNode<T>( x, null, null );

        int compareResult = x.compareTo( t.element );

        if( compareResult < 0 )
        {
            t.left = insert( x, t.left );//将x插入左子树中
            if( height( t.left ) - height( t.right ) == 2 )//打破平衡
                if( x.compareTo( t.left.element ) < 0 )//LL型(左左型)
                    t = rotateWithLeftChild( t );
                else   //LR型(左右型)
                    t = doubleWithLeftChild( t );
        }
        else if( compareResult > 0 )
        {
            t.right = insert( x, t.right );//将x插入右子树中
            if( height( t.right ) - height( t.left ) == 2 )//打破平衡
                if( x.compareTo( t.right.element ) > 0 )//RR型(右右型)
                    t = rotateWithRightChild( t );
                else                           //RL型
                    t = doubleWithRightChild( t );
        }
        else
            ;  // 重复数据,什么也不做
        t.height = Math.max( height( t.left ), height( t.right ) ) + 1;//更新高度
        return t;
    }

当然我们需要一个计算以某个节点为根节点高度的方法

 private int height( AvlNode<T> t )
    {
        return t == null ? -1 : t.height;
    }
原文地址:https://www.cnblogs.com/winAlaugh/p/5449295.html