AVL树的实现(C++)

AVL树,即平衡二叉搜索树,并且其左右子树的高度相差小于等于1。

AVL树的实现,在于插入节点的同时,保持树的平衡性。共分为如下四种旋转:

1. 左单边右旋转

当在k1的左子树上插入节点以后,导致K2失去平衡后的旋转。

代码实现如下:

      /*
    *
    * 左单边向右旋转
    */
    void singleRotateWithLeft(AvlNode * & k2)
    {
        AvlNode * k1 = k2->left;
        k2->left = k1->right;
        k1->right = k2;

        k2->h = max(h(k2->left), h(k2->right)) + 1;
        k1->h = max(h(k1->left), h(k1->right)) + 1;

        k2 = k1;
    }

2. 右单边左旋转

 当在K2点右子树上插入节点后,导致的旋转,如下图;

代码如下:

代码如下:

       /*
    *
    * 右单边向左旋转
    *
    */
    void singleRotateWithRight(AvlNode * & k1)
    {
        AvlNode * k2 = k1->right;
        k1->right = k2->left;
        k2->left = k1;

        k1->h = max(h(k1->left), h(k1->right)) + 1;
        k2->h = max(h(k2->left), h(k2->right)) + 1;

        k1 = k2;
    }

 

3. 左边2次旋转:

 当在K1的右子树上插入节点,导致K3失去平衡后的旋转。此时,需要做2次旋转。

a. 以K1为根,进行右单边左旋转

b. 以K3为根,进行左单边右旋转

代码如下:

      /*
    *
    * 左单边向右doube旋转    
    */
    void doubleRotateWithLeft(AvlNode * & node)
    {
        singleRotateWithRight(node->left);
        singleRotateWithLeft(node);
    }

 

4. 右边2次旋转

 

 

代码

       /*
    *
    * 右单边向左doube旋转
    */
    void doubleRotateWithRight(AvlNode * & node)
    {
        singleRotateWithLeft(node->right);
        singleRotateWithRight(node);
    }

 

all code :

 

class MyAVLTree
{
private:
    struct AvlNode {
        int val;
        AvlNode * left;
        AvlNode * right;
        int h;
        AvlNode(int x) : val(x), h(0), left(NULL), right(NULL) {}

    };

    AvlNode * root;

    static const int ALLOWED_IMBALANCE = 1;

public:

    MyAVLTree():root(NULL) {}
    AvlNode * getHead()
    {
        return root;
    }

    int h(AvlNode * root)
    {
        return root == NULL ? 0 : root->h;
    }

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

    void insert(int value,AvlNode * & node)
    {
        if (node == NULL)
        {
            node = new AvlNode{value};
        }
        else if (value < node->val) {
            insert(value, node->left);
        }
        else if (value > node->val)
        {
            insert(value, node->right);
        }

        balance(node);
    }

    void balance(AvlNode * & node)
    {
        if (node == NULL)
        {
            return;
        }

        if (h(node->left) - h(node->right) > ALLOWED_IMBALANCE)
        {
            if (h(node->left->left) >= h(node->left->right))
            {
                singleRotateWithLeft(node);
            }
            else
            {
                doubleRotateWithLeft(node);
            }
        }
        else if (h(node->right) - h(node->left) > ALLOWED_IMBALANCE)
        {
            if (h(node->right->right) >= h(node->right->left))
            {
                singleRotateWithRight(node);
            }
            else
            {
                doubleRotateWithRight(node);
            }
        }


        node->h = max(h(node->left), h(node->right)) + 1;
    }

    /*
    *
    * 左单边向右旋转

            k2                    k1
        k1     z    ==>       x         k2
    x       y                        y        z

    */
    void singleRotateWithLeft(AvlNode * & k2)
    {
        AvlNode * k1 = k2->left;
        k2->left = k1->right;
        k1->right = k2;

        k2->h = max(h(k2->left), h(k2->right)) + 1;
        k1->h = max(h(k1->left), h(k1->right)) + 1;

        k2 = k1;
    }

    /*
    *
    * 右单边向左旋转
    *        k1                         k2
    *   x       k2         ==>      k1      z
    *        y      z            x     y
    *
    *
    */
    void singleRotateWithRight(AvlNode * & k1)
    {
        AvlNode * k2 = k1->right;
        k1->right = k2->left;
        k2->left = k1;

        k1->h = max(h(k1->left), h(k1->right)) + 1;
        k2->h = max(h(k2->left), h(k2->right)) + 1;

        k1 = k2;
    }

    /*
    *
    * 左单边向右doube旋转    
    */
    void doubleRotateWithLeft(AvlNode * & node)
    {
        singleRotateWithRight(node->left);
        singleRotateWithLeft(node);
    }


    /*
    *
    * 右单边向左doube旋转
    */
    void doubleRotateWithRight(AvlNode * & node)
    {
        singleRotateWithLeft(node->right);
        singleRotateWithRight(node);
    }


    int max(int a, int b)
    {
        return a > b ? a : b;
    }

    void printAvlTreeWithPreOder(AvlNode * node)
    {
        
        if (node == NULL)
        {
            return;
        }
        cout << node->val << " ";
        printAvlTreeWithPreOder(node->left);
        printAvlTreeWithPreOder(node->right);
    }

    void printAvlTreeWithInOder(AvlNode * node)
    {

        if (node == NULL)
        {
            return;
        }
        printAvlTreeWithInOder(node->left);
        cout << node->val << " ";
        printAvlTreeWithInOder(node->right);
    }



};

 

posted @ 2019-02-25 18:39  ordi  阅读(195)  评论(0编辑  收藏  举报