AVL樹的進一步實現

代碼:

#pragma once
#include<iostream>
using namespace std;

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;       // 平衡因子:right-left
};


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(NULL==_pRoot)
        {
            _pRoot=new Node(key,value);
            return true;
        }
        //找到要插入的位置
        Node* pCur=_pRoot;
        Node* pParent=NULL;
        while(pCur)
        {
            if(key<pCur->_key)
            {
                pParent=pCur;
                pCur=pCur->_pLeft;
            }
            else if(key>pCur->_key)
            {
                pParent=pCur;
                pCur=pCur->_pRight;
            }
            else
                return false;

        }
        pCur=new Node(key,value);
        if(key<pParent->_key)
            pParent->_pLeft=pCur;
        else
            pParent->_pRight=pCur;
        pCur->_pParent=pParent;
        //已經插入,更新平衡因子,當不滿足AVL時進行旋轉
        while(pParent)//更新到根節點
        {
            if(pCur==pParent->_pLeft)
                pParent->_bf--;
            else
                pParent->_bf++;
            if(0==pParent->_bf)//插入前雙親有左子樹或右子樹,插入後無需更新_bf
                return true;
            else if(1==pParent->_bf||-1==pParent->_bf)//插入前雙親爲葉子結點,直接向上走
            {
                pCur=pParent;
                pParent=pParent->_pParent;
            }
            else//同號單旋,異號雙旋
            {
                if(2==pParent->_bf)
                {
                    if(1==pCur->_bf)
                        _RotateLeft(pParent);
                    else if(-1==pCur->_bf)
                        _RotateRL(pParent);
                }
                else
                {
                    if(-1==pCur->_bf)
                        _RotateRight(pParent);
                    else if(1==pCur->_bf)
                        _RotateLR(pParent);
                }
                break;
            }

        }
     // return true;
    }

    void InOrder()
    {
        cout<<"InOrder: ";
        _InOrder(_pRoot);
        cout<<endl;
    }

    size_t Height()
    {
        return _Height(_pRoot);
    }

    bool IsBalanceTree()
    {
        return _IsBalanceTree(_pRoot);
    }
private:
    // 檢測二叉樹是否爲平衡樹?
    bool _IsBalanceTree(Node* pRoot)
    {
        if(NULL==pRoot)
            return true;
        int LeftHeight=_Height(pRoot->_pLeft);
        int RightHeight=_Height(pRoot->_pRight);
        if(pRoot->_bf!=(RightHeight-LeftHeight)||abs(pRoot->_bf)>=2)
            return false;
        return _IsBalanceTree(pRoot->_pLeft) && _IsBalanceTree(pRoot->_pRight);
    }
    size_t _Height(Node* pRoot)
    {
        int hl=0;
        int hr=0;
        int max=0;
        if(pRoot!=NULL)
        {
            hl=_Height(pRoot->_pLeft);
            hr=_Height(pRoot->_pRight);
            max=hl>hr?hl:hr;
            return max+1;
        }
        else
            return 0;
    }

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

    void _RotateLeft(Node* pParent)
    {
        Node* pSubR=pParent->_pRight;
        Node* pSubRL=pSubR->_pLeft;

        pParent->_pRight=pSubRL;
        if(pSubRL)
            pSubRL->_pParent=pParent;
        pSubR->_pLeft=pParent;
        Node* pPParent=pParent->_pParent;
        pParent->_pParent=pSubR;
        pSubR->_pParent=pPParent;
        if(pPParent==NULL)
            _pRoot=pSubR;
        else
        {
            if(pPParent->_pLeft==pParent)
                pPParent->_pLeft=pSubR;
            else
                pPParent->_pRight=pSubR;
        }
        pSubR->_bf=pParent->_bf=0;
    }
    void _RotateRight(Node* pParent)
    {
        Node* pSubL=pParent->_pLeft;
        Node* pSubLR=pSubL->_pRight;

        pParent->_pLeft=pSubLR;
        if(pSubLR)
            pSubLR->_pParent=pParent;
        pSubL->_pRight=pParent;
        Node* pPParent=pParent->_pParent;
        pParent->_pParent=pSubL;
        pSubL->_pParent=pPParent;
        if(pPParent==NULL)
            _pRoot=pSubL;
        else
        {
            if(pPParent->_pLeft==pParent)
                pPParent->_pLeft=pSubL;
            else
                pPParent->_pRight=pSubL;
        }
        pSubL->_bf=pParent->_bf=0;
    }

    void _RotateLR(Node* pParent)
    {
        Node* pSubL=pParent->_pLeft;
        Node* pSubLR=pSubL->_pRight;
        int bf=pSubLR->_bf;
        _RotateLeft(pParent->_pLeft);
        _RotateRight(pParent);
        if(-1==bf)
            pParent->_bf=1;
        else if(1==bf)
            pSubL->_bf=-1;
    }
    void _RotateRL(Node* pParent)
    {
        Node* pSubR=pParent->_pRight;
        Node* pSubRL=pSubR->_pLeft;
        int bf=pSubRL->_bf;
        _RotateRight(pParent->_pRight);
        _RotateLeft(pParent);
        if(1==bf)
            pParent->_bf=-1;
        else if(-1==bf)
            pSubR->_bf=1;
    }
private:
    Node* _pRoot;
};


void TestAVL()
{
    //int array[] = {16, 3, 7, 11, 9, 26, 18, 14, 15};
    int array[] = {4, 2, 6, 1, 3, 5, 15, 7, 16, 14};
    AVLTree<int, int> t;
    for(size_t idx = 0; idx < sizeof(array)/sizeof(array[0]); ++idx)
        t.Insert(array[idx], idx);

    t.InOrder();

    if(t.IsBalanceTree())
    {
        cout<<"是AVL樹"<<endl;
    }
    else
    {
        cout<<"不是AVL樹"<<endl;
    }
}

int main()
{
    TestAVL();
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章