1. 程式人生 > >AVL樹的實現(C++)

AVL樹的實現(C++)

同時 ota 等於 左右子樹 sin == double 旋轉 struct

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);
    }



};

AVL樹的實現(C++)