C++平衡二叉树(AVL)

来源:互联网 发布:linux下查看用户权限 编辑:程序博客网 时间:2024/06/16 19:25

平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
当二叉树不平衡时,可以通过左单旋,右单旋,左右双旋,右左双旋的方式将它调整平衡;
平衡因子=左右子树高度之差[-1,1]
如图:
左单旋:
左单旋
右单旋:
右单旋
左右双旋:
左右双旋
右左双旋:
右左双旋

#include<iostream>using namespace std;template<class K,class V>struct AVLTreeNode{    AVLTreeNode(const K& key, const V& value)    : _key(key)    , _value(value)    , pLeft(NULL)    , pRight(NULL)    , pParent(NULL)    , _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{public:    AVLTree()    :_pRoot(NULL)    {}    bool Insert(const K& key, const V& value)    {        if (_pRoot == NULL)        {            _pRoot = new AVLTreeNode<K,V>(key,value);            return true;        }        AVLTreeNode<K, V>* pCur = _pRoot;        AVLTreeNode<K, V>* parent = NULL;        while (pCur)        {        //若节点存在,则不必插入        //若节点的值小于key,则key插入节点的右子树        //若节点的值大于key,则key插入节点的左子树            if (key == pCur->_key)                return false;            if (key > pCur->_key)            {                parent = pCur;                pCur = pCur->pRight;            }            else if(key < pCur->_key)            {                parent = pCur;                 pCur = pCur->pLeft;            }        }        //插入节点,并给出孩子节点与双亲结点的关系        pCur = new AVLTreeNode<K,V>(key, value);        if (key>parent->_key)        {            parent->pRight = pCur;            pCur->pParent = parent;        }        else        {            parent->pLeft = pCur;            pCur->pParent = parent;        }        //更新平衡因子(右子树高度-左子树高度[-1,1])        while (parent)        {        //若当前节点是双亲结点的左孩子,平衡因子-1        //若当前节点是双亲结点的右孩子,平衡因子+1            if (parent->pLeft == pCur)                parent->_bf--;            if (parent->pRight == pCur)                parent->_bf++;            if (parent->_bf == 0)                return true;            else            {                if (parent->_bf == 1 || parent->_bf == -1)                {                    pCur = parent;                    parent = parent->pParent;                }                else                {                    //同号单旋(正左负右),异号双旋                    if (parent->_bf == 2)                    {                        if (pCur->_bf == -1)//右左双旋                            _RotateRL(parent);                        else if (pCur->_bf == 1)//左单旋                            _RotateL(parent);                    }                    else if (parent->_bf == -2)                    {                        if (pCur->_bf == 1)//左右双旋                            _RotateLR(parent);                        else if (pCur->_bf == -1)//右单旋                            _RotateR(parent);                    }                    break;                }            }        }        return true;    }private:    //右单旋    void _RotateR(AVLTreeNode<K, V>*& parent){    AVLTreeNode<K, V>* subL = parent->pLeft;    AVLTreeNode<K, V>* subLR = subL->pRight;    parent->pLeft = subLR;    if (subLR != NULL)        subLR->pParent = parent;    subL->pRight = parent;    subL->pParent = parent->pParent;    AVLTreeNode<K, V>* rPrarent = parent->pParent;    parent->pParent = subL;    if (rPrarent == NULL)    {        _pRoot = subL;    }    else    {        if (rPrarent->pLeft == parent)            rPrarent->pLeft = subLR;        else            rPrarent->pRight = subLR;    }    parent->_bf = subL->_bf = 0;}    //左单旋void _RotateL(AVLTreeNode<K, V>*& parent){    AVLTreeNode<K, V>* subR = parent->pRight;    AVLTreeNode<K, V>* subRL = subR->pLeft;    parent->pRight = subRL;    if (subRL != NULL)        subRL->pParent =parent;    subR->pLeft = parent;    subR->pParent = parent->pParent;    AVLTreeNode<K, V>* rPrarent = parent->pParent;    if (rPrarent == NULL)        _pRoot = subR;    else    {        if (rPrarent->pLeft == parent)            rPrarent->pLeft = subR;        else            rPrarent->pRight = subR;    }    parent->_bf  = subR->_bf = 0;}//右左双旋void _RotateRL(AVLTreeNode<K, V>*& parent){    AVLTreeNode<K, V>* subR = parent->pRight;    AVLTreeNode<K, V>* subRL = subR->pLeft;    int bf = subRL->_bf;//0.1,-1    //右单旋    _RotateR(parent->pRight);    //左单旋    _RotateL(parent);    if (bf == -1)    {        parent->_bf = 0;        subR->_bf = 1;        subRL->_bf = 0;    }    else if (bf == 1)    {        parent->_bf = -1;        subR->_bf = 0;        subRL->_bf = 0;    }}//左右双旋void _RotateLR(AVLTreeNode<K, V>*& parent){    AVLTreeNode<K, V>* subL = parent->pLeft;    AVLTreeNode<K, V>* subLR = subL->pRight;    int bf = subLR->_bf;//0,1,-1    //左单旋    _RotateL(parent->pLeft);    //右单旋    _RotateR(parent);    if (bf == -1)    {        parent->_bf = 1;         subLR->_bf = 0;        subL->_bf = 0;    }    else if (bf==1)    {        parent->_bf = 0;        subLR->_bf = 0;        subL->_bf = -1;    }}private:    AVLTreeNode<K, V>* _pRoot;};测试函数:void AVLTreeTest(){    AVLTree<int, int> at;    int arr[] = { 50, 40, 60, 30, 45, 42 };    //int arr[] = { 50, 40, 30, 45, 20, 60 };    for (int idx = 0; idx < sizeof(arr) / sizeof(arr[0]); idx++)    {        at.Insert(arr[idx],arr[idx]);    }}
0 0
原创粉丝点击