二叉平衡树代码实现

节点设置

template<class K,class V>
struct AVLTreeNode
{
    AVLTreeNode(const K& key,const V& value)
        :_pLeft(NULL)
        ,_pRight(NULL)
        ,_pParent(NULL)
        ,_key(key)
        ,_value(value)
        ,_bf(0)
    {}
    AVLTreeNode<K,V>* _pLeft;
    AVLTreeNode<K,V>* _pRight;
    AVLTreeNode<K,V>* _pParent;
    K _key;
    V _value;
    int _bf;//平衡因子
};

AVL树的建立

template<class K,class V>
class AVLTree
{
    typedef AVLTreeNode<K,V> Node;
public:
    AVLTree()
        :_pRoot(NULL)
    {}
    //插入节点
    bool Insert(const K& key,const V& value)
    {
        //如果是空树则直接让根节点指向
        if(_pRoot == NULL)
        {
            _pRoot = new Node(key,value);
            return true;
        }
        //如果树不为空,则找到插入该节点的位置
        Node* pCur = _pRoot;
        Node* parent = NULL;
        while(pCur)
        {
            if(key < pCur->_key )
            {
                parent = pCur;
                pCur = pCur->_pLeft ;
            }
            else if(key > pCur->_key )
            {
                parent = pCur;
                pCur = pCur->_pRight ;
            }
            else 
                break;
        }
        //插入该节点
        pCur = new Node(key,value);
        if(parent->_key < key)
        {
            parent->_pRight = pCur;
            pCur->_pParent = parent;
        }
        else if(parent->_key > key)
        {
            parent->_pLeft = pCur;
            pCur->_pParent = parent;
        }
        //更新平衡因子
        while(parent)
        {
            if(pCur == parent->_pLeft )
                parent->_bf--;
            else if(pCur == parent->_pRight )
                parent->_bf++;
            if(parent->_bf == 0)
                break;
            else if(parent->_bf == 1 || parent->_bf == -1)
            {
                pCur = parent;
                parent = pCur->_pParent ;
            }
            else
            {
                if(parent->_bf == -2)
                {
                    Node* pSubL = parent->_pLeft ;
                    if(pSubL->_bf == -1)
                        _RotateR(parent);
                    else
                        _RotateLR(parent);
                }
                else if(parent->_bf == 2)
                {
                    Node* pSubR = parent->_pRight ;
                    if(pSubR->_bf == 1)
                        _RotateL(parent);
                    else
                        _RotateRL(parent);
                }
                break;
            }
        }
        return true;
    }
    //判断是否为AVL树
    bool IsBalanceTree()
    {
        return _IsBalanceTree(_pRoot);
    }
    void InOrder()
    {
        cout<<"InOrder:";
        _InOrder(_pRoot);
        cout<<endl;
    }
private:
    void _InOrder(Node* pRoot)
    {
        if(pRoot)
        {
            _InOrder(pRoot->_pLeft );
            cout<<pRoot->_key <<" ";
            _InOrder(pRoot->_pRight );
        }
    }
    //右旋
    void _RotateR(Node* parent)
    {
        Node* pSubL = parent->_pLeft ;
        Node* pSubLR = pSubL->_pRight ;

        parent->_pLeft = pSubLR;
        if(pSubLR)
            pSubLR->_pParent = parent;

        pSubL->_pRight = parent;
        Node* ppNode = parent->_pParent ;//保存祖父节点
        //pSubL->_pParent = ppNode;
        parent->_pParent = pSubL;

        if(ppNode == NULL)
        {
            _pRoot = pSubL;
            pSubL->_pParent = NULL;
        }
        else
        {
            if(ppNode->_pLeft == parent)
                ppNode->_pLeft = pSubL;
            else if(ppNode->_pRight == parent)
                ppNode->_pRight = pSubL;
            pSubL->_pParent = ppNode;
        }
        parent->_bf = 0;
        pSubL->_bf = 0;
    } 
    //左旋
    void _RotateL(Node* parent)
    {
        Node* pSubR = parent->_pRight ;
        Node* pSubRL = pSubR->_pLeft ;

        parent->_pRight = pSubRL;
        if(pSubRL)
            pSubRL->_pParent = parent;

        pSubR->_pLeft = parent;
        Node* ppNode = parent->_pParent ;
        parent->_pParent = pSubR;
        if(ppNode == NULL)
        {
            _pRoot = pSubR;
            pSubR->_pParent = NULL;
        }
        else
        {
            if(ppNode->_pLeft == parent)
                ppNode->_pLeft = pSubR;
            else if(ppNode->_pRight == parent)
                ppNode->_pRight = pSubR;
            pSubR->_pParent = ppNode;
        }
        pSubR->_bf = parent->_bf = 0;
    }  
    //先右后左双旋
    void _RotateRL(Node* parent)
    {
        Node* pSubR = parent->_pRight ;
        Node* pSubRL = pSubR->_pLeft ;
        int bf = pSubRL->_bf ;

        _RotateR(parent->_pRight );
        _RotateL(parent);
        //更新平衡因子
        if(bf == 0)
            parent->_bf = pSubRL->_bf = 0;
        else if(bf == 1)
        {
            pSubR->_bf = 0;
            parent->_bf = -1;
            pSubRL->_bf = 0;
        }
        else
        {
            parent->_bf = 0;
            pSubR->_bf = 1;
            pSubRL->_bf = 0;
        }
    }
    //先左后右双旋
    void _RotateLR(Node* parent)
    {
        Node* pSubL = parent->_pLeft ;
        Node* pSubLR = pSubL->_pRight ;
        int bf = pSubLR->_bf ;

        _RotateL(parent->_pLeft );
        _RotateR(parent);

        if(bf == 0)
        {
            pSubLR->_bf  = parent->_bf = pSubL->_bf = 0;
        }
        else if(bf == 1)
        {
            parent->_bf = 0;
            pSubL->_bf = -1;
            pSubLR->_bf = 0;
        }
        else
        {
            pSubL->_bf = 0;
            pSubLR->_bf = 0;
            parent->_bf = 1;
        }
    }
    //判断是否是二叉平衡树
    bool _IsBalanceTree(Node* pRoot)
    {
        if(pRoot == NULL)
            return true;
        int left = _Height(pRoot->_pLeft );
        int right = _Height(pRoot->_pRight );

        if(abs(right - left)>1)
            return false;
        return _IsBalanceTree(pRoot->_pLeft ) && _IsBalanceTree(pRoot->_pRight );
    } 
    //计算树的高度
    size_t _Height(Node* pRoot)
    {
        if(pRoot == NULL)
            return 0;
        int left = _Height(pRoot->_pLeft );
        int right = _Height(pRoot->_pRight );
        return left<right ? right+1 : left+1;
    } 
private:
    Node* _pRoot;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值