C++日期类的实现

AVL树又称为高度平衡的二叉搜索树,是1962年有俄罗斯的数学家G.M.Adel’son-Vel’skii和E.M.Landis提出来的。它能保持二叉树的高度
平衡,尽量降低二叉树的高度,减少树的平均搜索长度。
AVL树的性质
1. 左子树和右子树的高度之差的绝对值不超过1
2. 树中的每个左子树和右子树都是AVL树
3. 每个节点都有一个平衡因子(balance factor–bf),任一节点的平衡因子是-1,0,1。(每个节点的平衡因子等于右子树的高度减去左子
树的高度 )
AVL树的效率
一棵AVL树有N个节点,其高度可以保持在logN,插入/删除/查找的时间复杂度也是logN。

template <class K,class V>
struct AVLTreeNode       //节点
{
    K _key;
    V _value;
    int _bf;
    AVLTreeNode<K, V>* _pLeft;
    AVLTreeNode<K, V>* _pRight;
    AVLTreeNode<K, V>* _parent;


    AVLTreeNode(const K key, const V value)
        :_key(key)
        , _value(value)
        , _bf(0)           //平衡因子
        , _pLeft(NULL)
        , _pRight(NULL)
        , _parent(NULL)                                   
    {}

};

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* Pparent = _pRoot;
        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;
            pCur->_parent = Pparent;
        }
        else
        {
            Pparent->_pRight = pCur;
            pCur->_parent = Pparent;

        }

        while (Pparent)                    //更新平衡因子
        {
            if (pCur == Pparent->_pLeft)
                Pparent->_bf--;
            else
                Pparent->_bf++;

            if (Pparent->_bf == 0)        //判断平衡因子
                break;
            else if (Pparent->_bf == -1 || Pparent->_bf == 1)
            {
                pCur = Pparent;
                Pparent = pCur->_parent;
            }
            else                                //平衡因子为2或-2 需要进行旋转
            {
                if (Pparent->_bf == -2)
                {
                    if (pCur->_bf == -1)
                    {
                        RotateR(Pparent);
                        break;
                    }
                    else
                    {
                        RotateLR(Pparent);
                        break;
                    }   
                }

                if (Pparent->_bf == 2)
                {
                    if (pCur->_bf == 1)
                    {
                        RotateL(Pparent);
                        break;
                    }
                    else
                    {
                        RotateRL(Pparent);
                        break;
                    }   
                }
            }
        }
    }


    void RotateR(Node* pParent)               //右旋
    {
        assert(pParent);
        Node* subL = pParent->_pLeft;
        Node* subLR = subL->_pRight;          //可能为空
        pParent->_pLeft = subLR;              //断开pparent的左
        if (subLR)
        {
            subLR->_parent = pParent;
        }
        subL->_pRight = pParent;

        Node* pNode = pParent->_parent;
        pParent->_parent = subL;


        if (pNode == NULL)                  //pParent为根节点
        {
            _pRoot = subL;
            subL->_parent = NULL;
        }

        else
        {
            if (pNode->_pLeft = pParent)
                pNode->_pLeft = subL;
            else                                 //pParent为Node的右孩子
                pNode->_pRight = subL;
            subL->_parent = pNode;
        }

        subL->_bf = pParent->_bf = 0;            //旋转后平衡
    }

    void RotateL(Node* pParent)              
    {
        assert(pParent);
        Node*subR = pParent->_pRight;
        Node*subRL = subR->_pLeft;
        pParent->_pRight = subRL;
        if (subRL)
        {
            subRL->_parent = pParent;
        }
        subR->_pLeft = pParent;
        Node* pNode = pParent->_parent;
        pParent->_parent = subR;

        if (pNode == NULL)
        {
            _pRoot = subR;
            subR->_parent = NULL;
        }
        else
        {
            if (pParent == pNode->_pLeft)
                pNode->_pLeft = subR;
            else
                pNode->_pRight = subR;

            subR->_parent = pNode;
        }
        subR->_bf = pParent->_bf = 0;
    }


    void RotateLR(Node* pParent)    //左右旋
    {
        assert(pParent);
        Node*subL = pParent->_pLeft;
        Node*subLR = subL->_pRight;
        int bf = subLR->_bf;

        RotateL(pParent->_pLeft);
        RotateR(pParent);

        if (bf == 1)
        {
            pParent->_bf = 0;
            subL->_bf = -1;
        }
        else if (bf == -1)
        {
            subL->_bf = 0;
            pParent->_parent->_bf = 1;
        }
        else
            subL->_bf = pParent->_bf = 0;

        subLR->_bf = 0;

    }

    void RotateRL(Node* pParent)
    {
        assert(pParent);
        Node*subR = pParent->_pRight;
        Node*subRL = subR->_pLeft;
        int bf = subRL->_bf;

        RotateR(pParent->_pRight);
        RotateL(pParent);

        if (bf == 1)
        {
            pParent->_bf = -1;
            subR->_bf = 0;
        }
        else if (bf == -1)
        {
            pParent->_bf = 0;
            subR->_bf = 1;
        }
        else
            subR->_bf = pParent->_bf = 0;

        subRL->_bf = 0;
    }


    int Height(Node* pRoot)
    {
        if (pRoot == NULL)
        return 0;

        int leftH = Height(pRoot->_pLeft);
        int rightH = Height(pRoot->_pRight);

        return leftH > rightH ? leftH + 1 : rightH + 1;
    }

    bool IsBalance()
    {
        return _IsBalance(_pRoot);
    }


private:
    bool _IsBalance(Node* p)
    {
        if (p == NULL)
            return false;
        int leftH = Height(p->_pLeft);
        int rightH = Height(p->_pRight);

        if (rightH - leftH != p->_bf)
            cout << "平衡因子异常" << p->_key << endl;

        return abs(rightH - leftH) < 2          //绝对值
            && _IsBalance(p->_pLeft)
            && _IsBalance(p->_pRight);
    }

    Node* _pRoot;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值