AVL树的类建立

AVL 树是带平衡条件的的二叉查找树。

这里所指的平衡条件是:每个结点的左子树和右子树的高度最多差1,空树的高度定义为-1

对一颗AVL树进行插入操作的时候,极大可能会破坏树的平衡,此时需要对结点进行调整,以满足AVL 树的平衡条件。

而不平衡的情况有以下4种:

(1)对t 的左儿子的左子树进行一次插入

(2)对t的左儿子的右子树进行一次插入

(3)对t的右儿子的左子树进行一次插入

(4)对t的右儿子的右子树进行一次插入

其中(1)、(4)所作的调整为单旋转,(2)、(3)所作的调整为双旋转(双旋转由2次单旋转构成)。

AVL树的结点声明

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

    AvlNode ( int e, AvlNode *l, AvlNode *r, int h )
        : element ( e ), left ( l ), right ( r ), height ( h ) {}
};

AVL树的类:

public部分

class AvlTree
{
public:
    AvlTree()
    {
        root = NULL;
    }

    AvlTree ( const AvlTree &rhs )
    {
        root = clone ( rhs.root );
    }

    const AvlTree & operator= ( const AvlTree &rhs )
    {
        if ( this != &rhs )
        {
            makeEmpty();
            root = clone ( rhs.root );
        }
        return *this;
    }

    ~AvlTree()
    {
        makeEmpty();
    }

    int height() const
    {
        return height ( root );
    }

    void insert ( int x )
    {
        insert ( x, root );
    }

    void makeEmpty()
    {
        makeEmpty ( root );
    }

private部分

private:
    AvlNode *root;


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

    void insert ( int x, AvlNode *&t )
    {
        if ( t == NULL )
            t = new AvlNode ( x, NULL, NULL, 0 );
        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 ( t->element < x )
        {
            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;
    }

    void rotateWithLeftChild ( AvlNode *&t )
    {
        AvlNode *k = t->left;
        t->left = k->right;
        k->right = t;
        t->height = max ( height ( t->left ), height ( t->right ) ) + 1;
        k->height = max ( height ( k->left ), t->height ) + 1;
        t = k;
    }

    void rotateWithRightChild ( AvlNode *&t )
    {
        AvlNode *k = t->right;
        t->right = k->left;
        k->left = t;
        t->height = max ( height ( t->left ), height ( t->right ) ) + 1;
        k->height = max ( t->height, height ( k->right ) ) + 1;
        t = k;
    }

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

    void doubleWithRightChild ( AvlNode *&t )
    {
        rotateWithLeftChild ( t->right );
        rotateWithRightChild ( t );
    }


    void makeEmpty ( AvlNode *&t )
    {
        if ( t != NULL )
        {
            makeEmpty ( t->left );
            makeEmpty ( t->right );
            delete t;
        }
        t = NULL;
    }

    AvlNode *clone ( AvlNode *t ) const
    {
        if ( t == NULL )
            return NULL;

        return new AvlNode ( t->element, clone ( t->left ), clone ( t->right ), t->height );
    }
};

对于AVL 树的查找、删除、遍历输出等操作的代码可参考二叉查找树类模板的实现。(AVL树本身就是一个二叉查找树)

    原文作者:AVL树
    原文地址: https://blog.csdn.net/jiangyoujiangyou_yue/article/details/40709341
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞