AVL树插入小结

来源:互联网 发布:utorrent linux 64位 编辑:程序博客网 时间:2024/06/06 06:49

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

  如果一棵二叉搜索树是高度平衡的,它就是AVL树。如果它有n个结点,其高度可保持在O(lgn),平均搜索时间复杂度O(lg(n))
  在二叉搜索树中,我们知道要插入一个元素,必须将他插到合适的位置,但是在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");}
原创粉丝点击