RBTree实作

#ifndef _KOK_RBTREE_H_
#define _KOK_RBTREE_H_
#pragma once

#include "Alloc.h"
#include "Utility.h"

namespace KOK
{
    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc = KOK::alloc>
    class CRBTree
    {
        enum __Color { R = 0, B = 1 };

        template <class NodeValue>
        struct CRBTreeNode
        {
            typedef CRBTreeNode<NodeValue>* LinkType;
            LinkType pParent;
            LinkType pLeft;
            LinkType pRight;
            __Color color;
            NodeValue value;

            static LinkType Minimun(LinkType x)
            {
                while(x->pLeft != NULL)
                {
                    x = x->pLeft;
                }
                return x;
            }
            static LinkType Maximun()
            {
                while(x->pRight != NULL)
                {
                    x = x->pRight;
                }
                return x;
            }

        };

    public:
        template <class V, class R, class P>
        struct CRBTreeIterator
        {
            typedef V ValueType;
            typedef R Reference;
            typedef P Pointer;
            typedef CRBTreeNode<ValueType>* LinkType;
            typedef CRBTreeIterator<ValueType, Reference, Pointer> Self;
            typedef CRBTreeIterator<Value, Value&, Value*> Iterator;
            typedef CRBTreeIterator<Value, const Value&, const Value*> ConstIterator;

        private:
            LinkType pNode_;

        private:
            void Increment()
            {
                if(pNode_->pParent->pParent == pNode_ && pNode_->color == __Color::R)
                    return;
                else if(pNode_->pRight)
                {
                    pNode_ = pNode_->pRight;
                    while(pNode_->pLeft)
                        pNode_ = pNode_->pLeft;
                }
                else
                {
                    LinkType pParent = pNode_->pParent;
                    while(pParent->pRight == pNode_)
                    {
                        pNode_ = pParent;
                        pParent = pParent->pParent;
                    }
                    if(pNode_->pRight != pParent)
                        pNode_ = pParent;
                }
            }

            void Decrement()
            {
                if(pNode_->pParent->pParent == pNode_ && pNode_->color == __Color::R)
                    pNode_ = pNode_->pRight;
                else if(pNode_->pLeft)
                {
                    pNode_ = pNode_->pLeft;
                    while(pNode_->pRight)
                        pNode_ = pNode_->pRight;
                }
                else
                {
                    LinkType pParent = pNode_->pParent;
                    while(pParent->pLeft == pNode_)
                    {
                        pNode_ = pParent;
                        pParent = pParent->pParent;
                    }

                    pNode_ = pParent;

                }
            }

        public:
            CRBTreeIterator(const LinkType& pNode)
            {
                this->pNode_ = pNode;
            }

            Self& operator ++()
            {
                Increment();
                return *this;
            }

            Self& operator ++(int)
            {
                Self temp = *this;
                Increment();
                return temp;
            }

            Self& operator --()
            {
                Decrement();
                return *this;
            }

            Self& operator --(int)
            {
                Self temp = *this;
                    Decrement();
                return temp;
            }

            Reference operator *() const
            {
                return pNode_->value;
            }

            Pointer operator ->() const
            {
                return &pNode_->value;
            }

            bool operator ==(const Self& other)
            {
                return (&other)->pNode_ == this->pNode_;
            }

            bool operator !=(const Self& other)
            {
                return !operator==(other);
            }

        };

    private:
        typedef CRBTreeNode<Value> Node;
        typedef KOK::CAllocAdapter<Node, Alloc> NodeAlloc;

    public:
        typedef Key KeyType;
        typedef Value ValueType;
        typedef Value* Pointer;
        typedef const Value* ConstPointer;
        typedef Value& Reference;
        typedef const Value& ConstReference;
        typedef size_t SizeType;
        typedef ptrdiff_t DiffType;

        typedef CRBTreeIterator<ValueType, Reference, Pointer> Iterator;

    protected:
        typedef CRBTreeNode<Value>* LinkType;

    protected:
        SizeType count_;
        Compare compare_;
        LinkType pHeader_;
        KeyOfValue keyOfValue_;

    protected:
        void DeleteNode(LinkType& pNode)
        {
            Destroy(&pNode->value);
            PutNode(pNode);
            pNode = NULL;
        }
        LinkType CreateNode(ConstReference value)
        {
            LinkType pNode = GetNode();
            pNode->pLeft = pNode->pRight = pNode->pParent = NULL;
            pNode->color = __Color::R;
            Construct(&pNode->value, value);
            return pNode;
        }
        LinkType GetNode() { return NodeAlloc::Allocate();}
        void PutNode(LinkType pNode) { NodeAlloc::Deallocate(pNode); }

        void Init()
        {
            pHeader_ = GetNode();
            pHeader_->color = __Color::R;
            pHeader_->pLeft = pHeader_->pRight = pHeader_;
            pHeader_->pParent = NULL;
            count_ = 0;
        }

        inline LinkType& LeftMost() const { return pHeader_->pLeft; }
        inline LinkType& RightMost() const { return pHeader_->pRight; }
        inline LinkType& Root() const { return pHeader_->pParent; }
        inline LinkType& Left(LinkType& pNode) const { return pNode->pLeft; }
        inline LinkType& Right(LinkType& pNode) const { return pNode->pRight; }
        inline LinkType& Parent(LinkType& pNode) const { return pNode->pParent; }

        void RotateLeft(LinkType pNode, LinkType& pRoot);
        void RotateRight(LinkType pNode, LinkType& pRoot);
        void BalanceAdjust(LinkType pNewNode, LinkType& pRoot);
        Iterator InsertAux(LinkType pParent, LinkType& pRoot, ConstReference value);
        bool DeleteAux(LinkType pNode, LinkType pParent, ConstReference value);
        void DeleteAdjust(LinkType pNode, LinkType pParent, LinkType& pRoot);
        void ClearAux(LinkType& pNode);
    public:
        CRBTree();
        ~CRBTree();

        inline KeyOfValue GetKeyOfValue() const { return keyOfValue_; }
        inline Compare GetCompare() const { return compare_; }

        inline SizeType GetSize() const { return count_; }
        inline ValueType MaxValue() const { return RightMost()->value; }
        inline ValueType MinValue() const { return LeftMost()->value; }

        inline Iterator Begin() const { return LeftMost(); }
        inline Iterator End() const { return pHeader_; }
        inline bool Empty() const { return count_ == 0;}

        Pair<Iterator, bool> InsertUnique(ConstReference value);
        Iterator InsertEqual(ConstReference value);
        int Delete(ConstReference value);

        void Clear();
        Iterator Find(const KeyType& key);
       
    private:
        CRBTree& operator =(const CRBTree&);
        CRBTree(const CRBTree&);
    };

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::ClearAux(LinkType& pNode)
    {
        if(pNode->pLeft != NULL)
            ClearAux(pNode->pLeft);
        if(pNode->pRight != NULL)
            ClearAux(pNode->pRight);
        DeleteNode(pNode);
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::Clear()
    {
        if(Empty())
            return;
        ClearAux(Root());
        RightMost() = LeftMost() = NULL;
        count_ = 0;
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::~CRBTree()
    {
        Clear();
        PutNode(pHeader_);
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::CRBTree()
    {
        Init();
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    typename CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::Iterator CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::Find(const KeyType& key)
    {
        LinkType y = pHeader_;
        LinkType x = Root();
        while(x != NULL)
        {
            if(!compare_(keyOfValue_(x->value), key))
            {
                y = x;
                x = x->pLeft;
            }
            else
            {
                x = x->pRight;
            }

        }
        Iterator i = Iterator(y);
        return i == End() || compare_(key, keyOfValue_(y->value)) ? End() : i;
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::RotateLeft(LinkType pNode, LinkType& pRoot)
    {
        LinkType pRight = pNode->pRight;
        pNode->pRight = pRight->pLeft;
        if(pRight->pLeft)
            pRight->pLeft->pParent = pNode;
        pRight->pParent = pNode->pParent;

        if(pRoot == pNode)
            pRoot = pRight;
        else if(pNode == pNode->pParent->pRight)
            pNode->pParent->pRight = pRight;
        else
            pNode->pParent->pLeft = pRight;

        pRight->pLeft = pNode;
        pNode->pParent = pRight;
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::RotateRight(LinkType pNode, LinkType& pRoot)
    {
        LinkType pLeft = pNode->pLeft;
        pNode->pLeft = pLeft->pRight;
        if(pLeft->pRight)
            pLeft->pRight->pParent = pNode;
        pLeft->pParent = pNode->pParent;

        if(pRoot == pNode)
            pRoot = pLeft;
        else if(pNode == pNode->pParent->pRight)
            pNode->pParent->pRight = pLeft;
        else
            pNode->pParent->pLeft = pLeft;

        pLeft->pRight = pNode;
        pNode->pParent = pLeft;
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::BalanceAdjust(LinkType pNewNode, LinkType& pRoot)
    {
        pNewNode->color = __Color::R;
        while(pNewNode != pRoot && pNewNode->pParent->color == __Color::R)
        {
            if(pNewNode == pNewNode->pParent->pLeft)
            {
                LinkType pSParent = pNewNode->pParent->pParent->pRight;
                if(pSParent && pSParent->color == __Color::R)
                {
                    pNewNode->pParent->pParent->color = __Color::R;
                    pNewNode->pParent->color = __Color::B;
                    pSParent->color = __Color::B;
                    pNewNode = pNewNode->pParent->pParent;
                }
                else
                {
                    if(pNewNode->pParent->pRight == pNewNode)
                    {
                        RotateLeft(pNewNode->pParent, pRoot);
                        pNewNode = pNewNode->pLeft;
                    }
                    pNewNode->pParent->color = __Color::B;
                    pNewNode->pParent->pParent->color = __Color::R;
                    RotateRight(pNewNode->pParent->pParent, pRoot);
                }
            }
            else
            {
                LinkType pSParent = pNewNode->pParent->pParent->pLeft;
                if(pSParent && pSParent->color == __Color::R)
                {
                    pNewNode->pParent->pParent->color = __Color::R;
                    pNewNode->pParent->color = __Color::B;
                    pSParent->color = __Color::B;
                    pNewNode = pNewNode->pParent->pParent;
                }
                else
                {
                    if(pNewNode->pParent->pLeft == pNewNode)
                    {
                        RotateRight(pNewNode->pParent, pRoot);
                        pNewNode = pNewNode->pRight;
                    }
                    pNewNode->pParent->color = __Color::B;
                    pNewNode->pParent->pParent->color = __Color::R;
                    RotateLeft(pNewNode->pParent->pParent, pRoot);
                }
            }
        }

        pRoot->color = __Color::B;
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    typename CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::Iterator CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::InsertAux(LinkType pParent, LinkType& pRoot, ConstReference value)
    {
        LinkType pNewNode;
        if(pParent == pHeader_ || compare_(keyOfValue_(value), keyOfValue_(pParent->value)))
        {
            pNewNode = CreateNode(value);
            Left(pParent) = pNewNode;

            if(pParent == pHeader_)
            {
                Root() = pNewNode;
                Right(pParent) = pNewNode;
            }
            else if(pParent == LeftMost())
            {
                LeftMost() = pNewNode;
            }
        }
        else
        {
            pNewNode = CreateNode(value);
            Right(pParent) = pNewNode;
            if(pParent == RightMost())
                RightMost() = pNewNode;
        }

        Parent(pNewNode) = pParent;

        BalanceAdjust(pNewNode, Root());
        count_++;
        return Iterator(pNewNode);
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    Pair<typename CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::Iterator, bool> CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::InsertUnique(ConstReference value)
    {
        LinkType pParent = pHeader_;
        LinkType pNode = Root();
        bool comp = true;

        while(pNode != NULL)
        {
            pParent = pNode;
            comp = compare_(keyOfValue_(value), keyOfValue_(pNode->value));
            pNode = comp ? Left(pNode) : Right(pNode);
        }

        Iterator iter = Iterator(pParent);
        if(comp)
            if(iter == Begin())
               return Pair<Iterator, bool>(InsertAux(pParent, Root(), value), true);
            else
                iter--;
        if(compare_(keyOfValue_(*iter), value))
            return Pair<Iterator, bool>(InsertAux(pParent, Root(), value), true);

        return Pair<Iterator, bool>(iter, false);
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    typename CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::Iterator CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::InsertEqual(ConstReference value)
    {
        LinkType pParent = pHeader_;
        LinkType pNode = Root();
        while(pNode != NULL)
        {
            pParent = pNode;
            pNode = compare_(keyOfValue_(value), keyOfValue_(pNode->value)) ? Left(pNode) : Right(pNode);
        }

        return InsertAux(pParent, Root(), value);
    }


    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::DeleteAdjust(LinkType pNode, LinkType pParent, LinkType& pRoot)
    {
        if(pNode == pParent->pLeft) //both of pParent's child node can not be NULL
        {
            Node node;
            LinkType pSNode; // pSNode can not be NULL due to the rule of RBTree

            if(pNode == NULL)
            {
                pNode = &node;
                pNode->color = __Color::B;
                Parent(pNode) = pParent;
            }
            else if(pNode->color == __Color::R)
            {
                pNode->color = __Color::B;
                return;
            }

            while(pNode != pRoot && pNode->color == __Color::B)
            {
                pSNode = Right(Parent(pNode));
                if(pSNode->color == __Color::R)
                {
                    pSNode->color = Parent(pNode)->color;
                    Parent(pNode)->color = __Color::R;
                    RotateLeft(Parent(pNode), pRoot);
                }
                else if((!Right(pSNode) || Right(pSNode)->color == __Color::B) && (!Left(pSNode) || Left(pSNode)->color == __Color::B))
                {
                    pSNode->color = __Color::R;
                    pNode = pNode->pParent;
                }
                else if((Left(pSNode) && Left(pSNode)->color == __Color::R) && (!Right(pSNode) || Right(pSNode)->color == __Color::B))
                {
                    pSNode->color == __Color::R;
                    Left(pSNode)->color == __Color::B;
                    RotateRight(pSNode, pRoot);
                }
                else if(Right(pSNode) || Right(pSNode)->color == __Color::R)
                {
                    pSNode->color = Parent(pNode)->color;
                    Parent(pNode)->color = __Color::B;
                    RotateLeft(Parent(pNode), pRoot);
                    pNode = Right(pSNode);
                }
            }

            pNode->color = __Color::B;
        }
        else if(pNode == pParent->pRight)
        {
            Node node;
            LinkType pSNode; // pSNode can not be NULL due to the rule of RBTree

            if(pNode == NULL)
            {
                pNode = &node;
                pNode->color = __Color::B;
                Parent(pNode) = pParent;
            }
            else if(pNode->color == __Color::R) // case 1: must in the front of all the cases.
            {
                pNode->color = __Color::B;
                return;
            }

            while(pNode != pRoot && pNode->color == __Color::B)
            {
                pSNode = Left(Parent(pNode));
                if(pSNode->color == __Color::R) //case 2:
                {
                    pSNode->color = Parent(pNode)->color;
                    Parent(pNode)->color = __Color::R;
                    RotateRight(Parent(pNode), pRoot);
                }
                else if((!Right(pSNode) || Right(pSNode)->color == __Color::B) && (!Left(pSNode) || Left(pSNode)->color == __Color::B)) // case 3:
                {
                    pSNode->color = __Color::R;
                    pNode = pNode->pParent;
                }
                else if((Right(pSNode) && Right(pSNode)->color == __Color::R) && (!Left(pSNode) || Left(pSNode)->color == __Color::B)) //case 4:
                {
                    pSNode->color == __Color::R;
                    Right(pSNode)->color == __Color::B;
                    RotateLeft(pSNode, pRoot);
                }
                else if(Left(pSNode) || Left(pSNode)->color == __Color::R) //case 5:
                {
                    pSNode->color = Parent(pNode)->color;
                    Parent(pNode)->color = __Color::B;
                    RotateRight(Parent(pNode), pRoot);
                    pNode = Left(pSNode);
                }
            }

            pNode->color = __Color::B;
        }
        else //when delete root node
            return;
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    bool CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::DeleteAux(LinkType pNode, LinkType pParent, ConstReference value)
    {
        if(pNode->pLeft == NULL && pNode->pRight == NULL)
        {
            __Color colTemp = pNode->color;

            if(LeftMost() == pNode)
                LeftMost() = pNode->pParent;
            if(RightMost() == pNode)
                RightMost() = pNode->pParent;
           
            if(pParent == pHeader_)
                pParent->pParent = NULL;

            if(pNode == pParent->pLeft)
                pParent->pLeft = NULL;
            else if(pNode == pParent->pRight)
                pParent->pRight = NULL;

            DeleteNode(pNode);
            if(colTemp != __Color::R) // dont need to fixup while the color of node deled is red.
                DeleteAdjust(NULL, pParent, Root());
            count_--;
        }
        else if(pNode->pLeft == NULL) //only condition: parent->color = black; rchild->color = red;
        {
            if(LeftMost() == pNode)
            {
                LinkType pRChild = pNode->pRight;
                while(pRChild->pLeft)
                    pRChild= pRChild->pLeft;
                LeftMost() = pRChild;
            }

            pNode->pRight->pParent = pNode->pParent;
            LinkType pTemp = pNode->pRight;

            if(pParent == pHeader_)
                pParent->pParent = pTemp;

            if(pNode == pParent->pLeft)
                pParent->pLeft = pTemp;
            else if(pNode == pParent->pRight)
                pParent->pRight = pTemp;

            DeleteNode(pNode);
            DeleteAdjust(pTemp, pParent, Root());
            count_--;
        }
        else if(pNode->pRight == NULL) //only condition: parent->color = black; lchild->color = red;
        {
            if(RightMost() == pNode)
            {
                LinkType pLChild = pNode->pLeft;
                while(pLChild->pRight)
                    pLChild= pLChild->pRight;
                RightMost() = pLChild;
            }
            pNode->pLeft->pParent = pNode->pParent;
            LinkType pTemp = pNode->pLeft;

            if(pParent == pHeader_)
                pParent->pParent = pTemp;

            if(pNode == pParent->pLeft)
                pParent->pLeft = pTemp;
            else if(pNode == pParent->pRight)
                pParent->pRight = pTemp;

            DeleteNode(pNode);
            DeleteAdjust(pTemp, pParent, Root());
            count_--;
        }
        else // dont need to fixup again, Delete() method has already done it.
        {
            LinkType pLChild = pNode->pLeft;
            while(pLChild->pRight)
                pLChild= pLChild->pRight;
            ValueType temp = pLChild->value;
            Delete(pLChild->value);
            pNode->value = temp;
            return true;
        }

        return false;
    }
   
    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    int CRBTree<Key, Value, KeyOfValue, Compare, Alloc>::Delete(ConstReference value)
    {
        LinkType pParent = pHeader_;
        LinkType pNode = Root();

        while(pNode != NULL)
        {
            if(compare_(keyOfValue_(value), keyOfValue_(pNode->value)))
            {
                pParent = pNode;
                pNode = Left(pNode);
            }
            else if(compare_(keyOfValue_(pNode->value), keyOfValue_(value)))
            {
                pParent = pNode;
                pNode = Right(pNode);
            }
            else
                break;
        }

        if(pNode == NULL)
            return 0;
       
        DeleteAux(pNode, pParent, value);
        return 1;
    }
   
}

#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值