二叉平衡树

AVL(Adelson-Velskii and Landis)树是带有平衡条件的二叉查找树。其每个结点的左子树和右子树的高度最多差1.

在高度为h的AVL树中,最少结点数S(h)=S(h1)+S(h2)+1。对于h=0,S(h)=1;h=1,S(h)=2

AVL的树的结点声明

struct AvlNode
{
    int element;
    AvlNode *left;
    AvlNode *right;
    int height;

    AvlNode(const int& theElement, AvlNode *lt, AvlNode* rt, int h = 0):element(theElement), left(lt), right(rt), height(h)
    {}
};

计算AVL结点高度的函数


int height( AvlNode *t )
{
    return (t==NULL)?-1:t->height;
}

执行单旋转的函数

单旋转

/**
* 将左边的树变成右边的树,并返回指向新根的指针.
*/
void* rotateWithLeftChild( AvlNode * &k2 )
{//给指针加引用,则可对指针的值做修改
    AvlNode *k1 = k2->left;
    k2->left = k1->right;
    k1->right = k2;
    k2->height = max( height(k2->left), height(k2->right) )+1;
    k1->height = max( height(k1->left), height(k1->right) )+1;
    return k1;
}

rotateWithRightChild与之对称。

执行双旋转的函数

双旋转

void doubleWithLeftChild( AvlNode * & k3)
{
    rotateWithRightChild( k3->left);
    rotateWithLeftChild(k3);
}

doubleWithRightChild与之对应。

AVL树的插入操作

/**
 * Interal method to insert into a subtree.
 * x is the item to insert.
 * t is the node that roots the subtree.
 * Set the new root of the subtree.
*/
void insert( const int & x, AvlNode * & t )
{
    if (t == NULL)
        t == new AvlNode( x, NULL, NULL );
    else if (x < t->element)
    {
        insert( x, t->left );
        if ( height( t->left ) - height( t->right) == 2 )
        {
            if ( x < t->left->element )
                rotateWithLeftChild( t );//在左孩子的左子树中插入
            else
                doubleWithLeftChild( t );//在左孩子的右子树中插入
        }
    }
    else if (x > t->element)
    {
        insert( x, t->right );
        if ( height( t->right ) - height( t->left) ) == 2 )
        {
            if (t->right->element < x)
                rotateWithRightChild( t );//在右孩子的右子树中插入
            else
                doubleWithRightChild( t );//在右孩子的左子树中插入
        }
    }
    else
    ;
    t->height = max( height( t->left ), height( t->right) ) + 1;
}

附录

在二叉树中插入元素共分为四类:
* 在左儿子的左子树中插入;
* 在左儿子的右子树中插入;
* 在右儿子的左子树中插入;
* 在右儿子的右子树中插入;
例如:
1.在左儿子的左子树中插入
左左

2.在右儿子的右子树中插入
右右

3.在左儿子的右子树中插入
左右

4.在右儿子的左子树中插入
右左

原文地址:https://www.cnblogs.com/happygirl-zjj/p/4574619.html