AVL树插入小结

一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树:
 1. 它的左右子树都是AVL树
 2. 左子树和右子树高度之差(简称平衡因子)的绝对值不超过1(-1、0、1)

  如果一棵二叉搜索树是高度平衡的,它就是AVL树。如果它有n个结点,其高度可保持在O(lgn),平均搜索时间复杂度O(lg(n))
  在二叉搜索树中,我们知道要插入一个元素,必须将他插到合适的位置,但是在AVL树中,不仅要插入到合适的位置,还要保证插入该元素之后这棵树是平衡搜索二叉树。

  关于如何调整一棵二叉树为平衡二叉树,这里就涉及到四种旋转:
  左单旋,右单旋,左右双旋,右左双旋。
  下边就每一种旋转都给出图示:
  《AVL树插入小结》
   这是需要左单旋的情况
   《AVL树插入小结》
   这是需要右单旋的情况
   《AVL树插入小结》
   这是需要右左双旋的情况
《AVL树插入小结》
  这是需要左右双旋的情况
代码如下

#include<iostream>
using namespace std;
template<class K,class V>
struct AVLTreeNode
{
    AVLTreeNode(const K &key, const V &value)
        :_key(key)
        , _value(value)
        , _pLeft(nullptr)
        , _pRight(nullptr)
        , _pParent(nullptr)
        , _bf(0)
    {}
    AVLTreeNode<K, V> *_pLeft;
    AVLTreeNode<K, V> *_pRight;
    AVLTreeNode<K, V> *_pParent;
    K _key;
    V _value;
    int _bf;
};
template<class K,class V>
class AVLTree
{
private:
    typedef AVLTreeNode<K, V> Node;
public:
    AVLTree() :_pRoot(nullptr)
    {}
    void InOrder()
    {
        cout << "InOrder:" << endl;
        _InOrder(_pRoot);
        cout << endl;
    }
    void Insert(const K &key, const V &value)
    {
        _Insert(_pRoot, key, value);
    }
    bool IsBalanceTree()
    {
        return _IsBalanceTree(_pRoot);
    }
private:
    bool _Insert(Node *pRoot, const K &key, const V &value)
    {
        if (nullptr == pRoot)
        {
            _pRoot = new Node(key, value);
            return true;
        }
        Node *pCur = pRoot;
        Node *parent = nullptr;
        while (pCur)
        {
            if (key < pCur->_key)
            {
                parent = pCur;
                pCur = pCur->_pLeft;
            }
            else if (key > pCur->_key)
            {
                parent = pCur;
                pCur = pCur->_pRight;
            }
            else
            {
                return false;
            }
        }
        pCur = new Node(key, value);
        if (key < parent->_key)
            parent->_pLeft = pCur;
        else
            parent->_pRight = pCur;
        pCur->_pParent = parent;
        if (pCur == parent->_pLeft)
            --parent->_bf;
        else
            ++parent->_bf;

        while (nullptr != parent)
        {
            if (0==parent->_bf)
                return true;
            else if (1 == parent->_bf || -1 == parent->_bf)
            {
                Node *ppParent = parent->_pParent;
                if (nullptr != ppParent)
                {
                    if (ppParent->_pLeft == parent)
                        ppParent->_bf--;
                    else
                        ppParent->_bf++;
                }
                parent = parent->_pParent;
            }
            else
            {
                if (2 == parent->_bf)
                {
                    if (1 == parent->_pRight->_bf)
                        _RotateL(parent);
                    else
                        _RotateRL(parent);
                }
                else
                {
                    if (-1 == parent->_pLeft->_bf)
                        _RotateR(parent);
                    else
                        _RotateLR(parent);
                }
                break;
            }

        }
        return true;
    }
    void _InOrder(Node *pRoot)
    {
        if (pRoot)
        {
            _InOrder(pRoot->_pLeft);
            cout << pRoot->_key << " ";
            _InOrder(pRoot->_pRight);
        }

    }
    void _RotateL(Node *parent)
    {
        Node *pSubR = parent->_pRight;
        Node *ppParent = parent ->_pParent;
        Node *pSubRL = pSubR->_pLeft;
        parent->_pRight = pSubRL;
        if (nullptr != pSubRL)
            pSubRL->_pParent = parent;
        pSubR->_pLeft = parent;
        parent->_pParent = pSubR;
        if (nullptr == ppParent)
        {
            _pRoot = pSubR;
            pSubR->_pParent = nullptr;
        }
        else
        {
            if (parent == ppParent->_pLeft)
                ppParent->_pLeft=pSubR;
            else
                ppParent->_pRight=pSubR;
            pSubR->_pParent = ppParent;
        }
        parent->_bf = pSubR->_bf = 0;
        parent = pSubR;
    }
    void _RotateR(Node *parent)
    {
        Node *pSubL = parent->_pLeft;
        Node *pSubLR = pSubL->_pRight;
        Node *ppParent = parent->_pParent;
        parent->_pLeft = pSubLR;
        if (pSubLR)
            pSubLR->_pParent = parent;
        pSubL->_pRight = parent;
        parent->_pParent = pSubL;
        if (nullptr == ppParent)
        {
            _pRoot = pSubL;
            pSubL->_pParent = nullptr;
        }
        else
        {
            if (parent == ppParent->_pLeft)
                ppParent->_pLeft = pSubL;
            else
                ppParent->_pRight = pSubL;
            pSubL->_pParent = ppParent;
        }
        pSubL->_bf = parent->_bf = 0;
        parent = pSubL;
    }
    void _RotateRL(Node *parent)
    {
        Node *pSubR = parent->_pRight;
        Node *pSubRL = pSubR->_pLeft;
        int SubRLf = pSubRL->_bf;
        _RotateR(parent->_pRight);
        _RotateL(parent);
        if (1 == SubRLf)
            parent->_bf = -1;
        else if (-1 == SubRLf)
            pSubR->_bf = 1;
    }
    void _RotateLR(Node *parent)
    {
        Node *pSubL = parent->_pLeft;
        Node *pSubLR = pSubL->_pRight;
        int SubLRf = pSubLR->_bf;
        _RotateL(parent->_pLeft);
        _RotateR(parent);
        if (-1 == SubLRf)
            parent->_bf = 1;
        else if (1 == SubLRf)
            pSubL->_bf = -1;

    }
    size_t _Height(Node *pRoot)
    {
        if (nullptr == pRoot)
            return 0;
        if (nullptr == pRoot->_pLeft&&nullptr == pRoot)
            return 1;
        size_t leftHeight = _Height(pRoot->_pLeft);
        size_t rightHeight = _Height(pRoot->_pRight);
        return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
    }
    bool _IsBalanceTree(Node *pRoot)
    {
        if (pRoot == nullptr)
            return true;

        int leftHeight = _Height(pRoot->_pLeft);
        int rightHeight = _Height(pRoot->_pRight);



        if (rightHeight - leftHeight != pRoot->_bf)
        {
            cout << "平衡因子错误" << endl;
            return false;
        }
        return (abs(leftHeight - rightHeight) <2)&&_IsBalanceTree(pRoot->_pLeft)&&_IsBalanceTree(pRoot->_pRight);
    }
private:
    Node *_pRoot;
};

void test1()
{
    int a[10] = { 3, 2, 1, 4, 5, 6, 7, 10, 9, 8 }; AVLTree<int, int> avl; for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) avl.Insert(a[i], a[i]); cout << avl.IsBalanceTree() << endl; avl.InOrder(); } void test2() { int array2[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 }; AVLTree<int, int> avl; for (int i = 0; i < sizeof(array2) / sizeof(array2[0]); i++) avl.Insert(array2[i], array2[i]); cout << avl.IsBalanceTree() << endl; avl.InOrder(); } void test3() { int array1[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 }; AVLTree<int, int> avl; for (int i = 0; i < sizeof(array1) / sizeof(array1[0]); i++) avl.Insert(array1[i], array1[i]); cout << avl.IsBalanceTree() << endl; avl.InOrder(); } int main() { test1(); test2(); test3(); system("pause"); }
    原文作者:AVL树
    原文地址: https://blog.csdn.net/gjggj/article/details/72621792
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞