AVLTree的实作

#ifndef _KOK_AVLTREE_H_
#define _KOK_AVLTREE_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 CAVLTree
    {
        enum __Balance { L = 1, B = 0, R = -1, H = 99};

        template <class NodeValue>
        struct CAVLTreeNode
        {
            typedef CAVLTreeNode<NodeValue>* LinkType;
            LinkType pParent;
            LinkType pLeft;
            LinkType pRight;
            __Balance balance;
            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 CAVLTreeIterator
        {
            typedef V ValueType;
            typedef R Reference;
            typedef P Pointer;
            typedef CAVLTreeNode<ValueType>* LinkType;
            typedef CAVLTreeIterator<ValueType, Reference, Pointer> Self;
            typedef CAVLTreeIterator<Value, Value&, Value*> Iterator;
            typedef CAVLTreeIterator<Value, const Value&, const Value*> ConstIterator;

        private:
            LinkType pNode_;

        private:
            void Increment()
            {
                if(pNode_->balance == __Balance::H)
                    pNode_ = pNode_;
                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_->balance == __Balance::H)
                    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:
            CAVLTreeIterator(const LinkType& pNode) //const is not necessory.LinkType is seem like a value type after typedef. Const is not necessory in value type coz temperarily copy. see blog topic "const and typedef"
            {
                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 CAVLTreeNode<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 CAVLTreeIterator<ValueType, Reference, Pointer> Iterator;

    protected:
        typedef CAVLTreeNode<Value>* LinkType;

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

    protected:
        void RotateLeft(LinkType& pRoot);
        void RotateRight(LinkType& pRoot);
        void LeftBalance(LinkType& pRoot);
        void RightBalance(LinkType& pRoot);
        void DelLeftAdjust(LinkType& pNode);
        void DelRightAdjust(LinkType& pNode);

        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->balance = __Balance::B;
            Construct(&pNode->value, value);
            return pNode;
        }
        LinkType GetNode() { return NodeAlloc::Allocate();}
        void PutNode(LinkType pNode) { NodeAlloc::Deallocate(pNode); }

        void DeleteAux(LinkType& pNode, ConstReference value, bool& shorter);
        int InnerDelete(LinkType& pNode, ConstReference value, bool& shorter);
        Pair<typename Iterator, bool> InsertAux(LinkType& pRoot, LinkType& pParent, ConstReference value, bool& taller, bool isUnique);

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

        void Init();
        void ClearAux(LinkType& pNode);
    public:
        CAVLTree();
        ~CAVLTree();

        Pair<Iterator, bool> InsertUnique(ConstReference value);
        Iterator InsertEqual(ConstReference value);
        int Delete(ConstReference value);
        void Clear();
        Iterator Find(const KeyType& key);

        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;}

    private:
        CAVLTree& operator =(const CAVLTree&);
        CAVLTree(const CAVLTree&);

    };

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::Init()
    {
        pHeader_ = GetNode();
        pHeader_->balance = __Balance::H;
        pHeader_->pLeft = pHeader_->pRight = pHeader_;
        pHeader_->pParent = NULL;
        count_ = 0;

    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CAVLTree<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 CAVLTree<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>
    typename CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::Iterator CAVLTree<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>
    CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::CAVLTree()
    {
        Init();
    }

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

    }

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

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

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::LeftBalance(LinkType &pRoot)
    {
        LinkType pLeft = pRoot->pLeft;
        switch(pLeft->balance)
        {
        case L:
            pRoot->balance = pLeft->balance = B;
            RotateRight(pRoot);
            break;
        case R:
            {
                LinkType pRChild = pLeft->pRight;
                switch(pRChild->balance)
                {
                case L:
                    pLeft->balance = B;
                    pRoot->balance = R;
                    break;
                case B:
                    pLeft->balance = pRoot->balance = B;
                    break;
                case R:
                    pRoot->balance = B;
                    pLeft->balance = L;
                    break;
                }
                pRChild->balance = B;
                RotateLeft(pLeft);
                RotateRight(pRoot);
                break;
            }
        case B:
            return;
        }
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::RightBalance(LinkType &pRoot)
    {
        LinkType pRight = pRoot->pRight;
        switch(pRight->balance)
        {
        case R:
            pRoot->balance = pRight->balance = B;
            RotateLeft(pRoot);
            break;
        case L:
            {
                LinkType pLChild = pRight->pLeft;
                switch(pLChild->balance)
                {
                case L:
                    pRight->balance = R;
                    pRoot->balance = B;
                    break;
                case B:
                    pRight->balance = pRoot->balance = B;
                    break;
                case R:
                    pRoot->balance = L;
                    pRight->balance = B;
                    break;
                }
                pLChild->balance = B;
                RotateRight(pRight);
                RotateLeft(pRoot);
                break;
            }
        case B:
            return;
        }
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    Pair<typename CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::Iterator, bool> CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::InsertAux(LinkType& pRoot, LinkType& pParent, ConstReference value, bool& taller, bool isUnique)
    {
        if(pRoot == NULL)
        {
            pRoot = CreateNode(value);
            pRoot->balance = __Balance::B;
            pRoot->pParent = pParent;
            pRoot->pRight= NULL;
            pRoot->pLeft = NULL;
            taller = true;
            count_++;

            if(pParent == LeftMost())
            {
                if(compare_(keyOfValue_(value), keyOfValue_(pParent->value)))
                {
                    LeftMost() = pRoot;
                }
            }

            if(pParent == RightMost())
            {
                if(!compare_(keyOfValue_(value), keyOfValue_(pParent->value)))
                {
                    RightMost() = pRoot;
                }
            }

            return Pair<Iterator, bool>(Iterator(pRoot), true);
        }
        else
        {
            if(compare_(keyOfValue_(pRoot->value), keyOfValue_(value)))
            {
                Pair<Iterator, bool> temp = InsertAux(pRoot->pRight, pRoot, value, taller, isUnique);
                if(!temp.second)
                    return temp;

                if(taller)
                {
                    switch(pRoot->balance)
                    {
                    case R:
                        RightBalance(pRoot);
                        taller = false;
                        break;
                    case B:
                        pRoot->balance = R;
                        taller = true;
                        break;
                    case L:
                        pRoot->balance = B;
                        taller = false;
                        break;
                    }
                }
                return temp;
            }
            else if(compare_(keyOfValue_(value), keyOfValue_(pRoot->value)))
            {
                Pair<Iterator, bool> temp = InsertAux(pRoot->pLeft, pRoot, value, taller, isUnique);
                if(!temp.second)
                    return temp;

                if(taller)
                {
                    switch(pRoot->balance)
                    {
                    case R:
                        pRoot->balance = B;
                        taller = false;
                        break;
                    case B:
                        pRoot->balance = L;
                        taller = true;
                        break;
                    case L:
                        LeftBalance(pRoot);
                        taller = false;
                        break;
                    }
                }
                return temp;
            }
            else
            {
                if(isUnique)
                    return Pair<Iterator, bool>(Iterator(pRoot), false);
                else
                {
                    Pair<Iterator, bool> temp = InsertAux(pRoot->pRight, pRoot, value, taller, isUnique);
                    if(!temp.second)
                        return temp;

                    if(taller)
                    {
                        switch(pRoot->balance)
                        {  
                        case R:
                            RightBalance(pRoot);
                            taller = false;
                            break;
                        case B:
                            pRoot->balance = R;
                            taller = true;
                            break;
                        case L:
                            pRoot->balance = B;
                            taller = false;
                            break;
                        }
                    }

                    return temp;
                }

            }
        }
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    Pair<typename CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::Iterator, bool> CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::InsertUnique(ConstReference value)
    {
        bool taller = false;

        if(Root() == NULL)
        {
            Root() = CreateNode(value);
            Root()->balance = __Balance::B;
            Root()->pParent = pHeader_;
            Root()->pRight= NULL;
            Root()->pLeft = NULL;
            pHeader_->pLeft = pHeader_->pRight = Root();
            taller = true;
            count_++;

            return Pair<Iterator, bool>(Iterator(Root()), true);
        }
        else
        {
            return InsertAux(Root(), pHeader_, value, taller, true);
        }

    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    typename CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::Iterator CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::InsertEqual(ConstReference value)
    {
        bool taller = false;

        if(Root() == NULL)
        {
            Root() = CreateNode(value);
            Root()->balance = __Balance::B;
            Root()->pParent = pHeader_;
            Root()->pRight= NULL;
            Root()->pLeft = NULL;
            pHeader_->pLeft = pHeader_->pRight = Root();
            taller = true;
            count_++;

            return Root();
        }
        else
        {
            return InsertAux(Root(), pHeader_, value, taller, false).first;
        }

    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::DelLeftAdjust(LinkType& pNode)
    {
        LinkType pLeft = pNode->pLeft;
        switch(pLeft->balance)
        {
        case B:
            pNode->balance = L;
            pLeft->balance = R;
            RotateRight(pNode);
            break;
        case L:
            pLeft->balance = B;
            pNode->balance = B;
            RotateRight(pNode);
            break;
        case R:
            pLeft->balance = B;
            pNode->balance = B;
            RotateLeft(pLeft);
            RotateRight(pNode);
            break;
        }
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::DelRightAdjust(LinkType& pNode)
    {
        LinkType pRight = pNode->pRight;
        switch(pRight->balance)
        {
        case B:
            pNode->balance = R;
            pRight->balance = L;
            RotateLeft(pNode);
            break;
        case L:
            pRight->balance = B;
            pNode->balance = B;
            RotateRight(pRight);
            RotateLeft(pNode);
            break;
        case R:
            pRight->balance = B;
            pNode->balance = B;
            RotateLeft(pNode);
            break;
        }
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    void CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::DeleteAux(LinkType& pNode, ConstReference value, bool& shorter)
    {
        if(pNode->pLeft == NULL && pNode->pRight == NULL)
        {
            if(LeftMost() == pNode)
                LeftMost() = pNode->pParent;
            if(RightMost() == pNode)
                RightMost() = pNode->pParent;

            DeleteNode(pNode);
            shorter = true;
            count_--;
        }
        else if(pNode->pLeft == NULL)
        {
            if(LeftMost() == pNode)
            {
                LinkType pRChild = pNode->pRight;
                while(pRChild->pLeft)
                    pRChild= pRChild->pLeft;
                LeftMost() = pRChild;
            }
            pNode->pRight->pParent = pNode->pParent;
            LinkType pTemp = pNode->pRight;
            DeleteNode(pNode);
            pNode = pTemp;

            shorter = true;
            count_--;
        }
        else if(pNode->pRight == NULL)
        {
            if(RightMost() == pNode)
            {
                LinkType pLChild = pNode->pLeft;
                while(pLChild->pRight)
                    pLChild= pLChild->pRight;
                RightMost() = pLChild;
            }
            pNode->pLeft->pParent = pNode->pParent;
            LinkType pTemp = pNode->pLeft;
            DeleteNode(pNode);
            pNode = pTemp;

            shorter = true;
            count_--;
        }
        else
        {
            LinkType pNodeTemp = pNode; //store pNode locate, coz after delete operation, pNode maybe changed.(pNode is ref)
            LinkType pLChild = pNode->pLeft;
            while(pLChild->pRight)
                pLChild= pLChild->pRight;
            ValueType temp = pLChild->value;
            Delete(pLChild->value);
            pNodeTemp->value = temp;
            shorter = false;
        }
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    int CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::InnerDelete(LinkType& pNode, ConstReference value, bool& shorter)
    {
        if(pNode == NULL)
            return 0;

        if(compare_(keyOfValue_(pNode->value), keyOfValue_(value)))
        {
            if(!InnerDelete(pNode->pRight, value, shorter))
                return 0;

            if(shorter)
            {
                switch(pNode->balance)
                {
                case B:
                    pNode->balance = L;
                    shorter = false;
                    break;
                case L:
                    DelLeftAdjust(pNode);
                    shorter = true;
                    break;
                case R:
                    pNode->balance = B;
                    shorter = true;
                    break;
                }
            }
        }
        else if(compare_(keyOfValue_(value), keyOfValue_(pNode->value)))
        {
            if(!InnerDelete(pNode->pLeft, value, shorter))
                return 0;

            if(shorter)
            {
                switch(pNode->balance)
                {
                case B:
                    pNode->balance = R;
                    shorter = false;
                    break;
                case L:
                    pNode->balance = B;
                    shorter = true;
                    break;
                case R:
                    DelRightAdjust(pNode);
                    shorter = true;
                    break;
                }
            }

        }
        else
        {
            DeleteAux(pNode, value, shorter);
        }
        return 1;
    }

    template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
    int CAVLTree<Key, Value, KeyOfValue, Compare, Alloc>::Delete(ConstReference value)
    {
        if(Root() == NULL)
            return 0;

        bool shorter = false;
        return InnerDelete(Root(), value, shorter);
    }

}
#endif

 

#ifndef _ALLOC_H_
#define _ALLOC_H_
#pragma once

#include <new>

#ifndef NULL
#define NULL 0
#endif

namespace KOK
{
    class __CSimpleAlloc
    {
    public:
        static void* Allocate(size_t n)
        {
            if(n != NULL) return ::operator new(n);
        }

        static void Deallocate(void* p)
        {
            if(p != NULL) return ::operator delete(p);
        }
    };

    template <class T, class Value>
    inline void Construct(T* p, Value& value)
    {
        new(p) T(value);
    }

    template <class T, class Value>
    inline void Construct(T* p)
    {
        new(p) T();
    }

    template <class T>
    inline void Destroy(T* p)
    {
        p->~T();
    }

#ifndef _USE_CUSTOM_ALLOC_
    typedef __CSimpleAlloc alloc;
#endif

    template <class T, class Alloc = alloc>
    class CAllocAdapter
    {
    public:
        static T* Allocate(size_t n)
        {
            return n == 0 ? 0 : (T*)Alloc::Allocate(n * sizeof(T));
        }

        static T* Allocate(void)
        {
            return (T*)Alloc::Allocate(sizeof(T));
        }

        static void Deallocate(T* p)
        {
            Alloc::Deallocate(p);
        }

        static void Deallocate(T* p, size_t n)
        {
            Alloc::Deallocate(p);
        }

    };
}
#endif

 

#ifndef _KOK_UTILITY_H_
#define _KOK_UTILITY_H_
#pragma once

namespace KOK
{
    template<class T1, class T2> struct Pair
 { 
 typedef Pair<T1, T2> Self;
 typedef T1 FirstType;
 typedef T2 SecondType;

    Pair(const FirstType& _first, const SecondType& _second) : first(_first), second(_second) {}

 FirstType first; 
 SecondType second;
 };

}

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值