C++平衡二叉树(AVL)

平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
当二叉树不平衡时,可以通过左单旋,右单旋,左右双旋,右左双旋的方式将它调整平衡;
平衡因子=左右子树高度之差[-1,1]
如图:
左单旋:
《C++平衡二叉树(AVL)》
右单旋:
《C++平衡二叉树(AVL)》
左右双旋:
《C++平衡二叉树(AVL)》
右左双旋:
《C++平衡二叉树(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(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]); } } 
    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/qq_35420908/article/details/70230611
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞