MaxHeep实作

#ifndef _KOK_MAXHEEP_H_
#define _KOK_MAXHEEP_H_
#pragma once

#include "Alloc.h"

namespace KOK
{
    template <class Value, class Compare, class Alloc = KOK::alloc>
    class CMaxHeep
    {
        template <class NodeValue>
        struct CMaxHeepNode
        {
            typedef CMaxHeepNode<NodeValue>* LinkType;
            LinkType pParent;
            LinkType pLeft;
            LinkType pRight;
            NodeValue value;
        };

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

        protected:
            typedef CMaxHeepNode<Value> Node;
            typedef CMaxHeepNode<Value>* LinkType;
            typedef KOK::CAllocAdapter<Node, Alloc> NodeAlloc;

        protected:
            LinkType pRoot;
            Compare keyCompare;
            int count;
            int fullCount;
            int depth;

        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;
                Construct(&pNode->value, value);
                return pNode;
            }
            LinkType GetNode() { return NodeAlloc::Allocate();}
            void PutNode(LinkType pNode) { NodeAlloc::Deallocate(pNode); }
           
            inline void Init() { pRoot = NULL; count = 0; fullCount = 0; depth = 0; }

            inline LinkType& Root() { return pRoot; }
            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 MaintainUp(LinkType pNode);
            void MaintainDown(LinkType pNode);

            LinkType PushHeepAux(ConstReference value)
            {
                count++;

                if(count > fullCount)
                {
                    fullCount += 1<<depth;
                    depth++;
                }

                if(Root() == NULL)
                {
                    Root() = CreateNode(value);
                    return Root();
                }

                int i = depth;
                LinkType pNode = Root();

                while(--i)
                {
                    if(i == 1)
                    {
                        if((count>>(i-1))& 1)
                        {
                            Right(pNode) = CreateNode(value);
                            Right(pNode)->pParent = pNode;
                            return Right(pNode);
                        }
                        else
                        {
                            Left(pNode) = CreateNode(value);
                            Left(pNode)->pParent = pNode;
                            return Left(pNode);
                        }
                    }
                    if((count>>(i-1))& 1)
                        pNode = Right(pNode);
                    else
                        pNode = Left(pNode);
                }
            }
           
            LinkType PopHeepAux()
            {
                int i = depth;
                LinkType pNode = Root();
 
                while(--i)
                {
                    if(i == 1)
                    {
                        if((count>>(i-1))& 1)
                        {
                            LinkType pTemp = pNode;
                            pNode = Right(pNode);
                            Right(pTemp) = NULL;
                            break;
                        }
                        else
                        {
                            LinkType pTemp = pNode;
                            pNode = Left(pNode);
                            Left(pTemp) = NULL;
                            break;
                        }
                    }
                    if((count>>(i-1))& 1)
                        pNode = Right(pNode);
                    else
                        pNode = Left(pNode);
                }

                count--;
                if(count <= fullCount - (1<<(depth - 1)))
                {
                    depth--;
                    fullCount -= 1<<depth;
                }
               
                return pNode;
            }
            void ClearAux(LinkType& pNode);

        public:
            CMaxHeep() { Init(); }
            ~CMaxHeep() { Clear(); }
               
            inline bool Empty() const { return count == 0;}

            inline Reference Top() const { return pRoot->value; }
            inline int GetSize() const { return count; }
            void PopHeep();
            void PushHeep(ConstReference value);
            void Clear();
           

    };

    template <class Value, class Compare, class Alloc>
    void CMaxHeep<Value, Compare, Alloc>::MaintainUp(LinkType pNode)
    {
        bool flag = false;
        ValueType tempValue = pNode->value;

        while(Parent(pNode) != NULL && !flag )
        {
            LinkType pTemp = Parent(pNode);
            if(keyCompare(pNode->value, pTemp->value))
                flag = true;
            else
            {
                pNode->value = pTemp->value;
                pNode = pTemp;
            }
        }

        pNode->value = tempValue;
    }

    template <class Value, class Compare, class Alloc>
    void CMaxHeep<Value, Compare, Alloc>::MaintainDown(LinkType pNode)
    {
        bool flag = false;
        ValueType tempValue = pNode->value;

        while(!flag && Left(pNode) != NULL)
        {
            LinkType pTemp = Left(pNode);
            if(Right(pNode) != NULL)
            {
                if(keyCompare(Left(pNode)->value, Right(pNode)->value))
                {
                    pTemp = Right(pNode);
                }
            }
            if(keyCompare(pTemp->value, pNode->value))
                flag = true;
            else
            {
                pNode->value = pTemp->value;
                pNode = pTemp;
            }
        }

        pNode->value = tempValue;
    }

    template <class Value, class Compare, class Alloc>
    void CMaxHeep<Value, Compare, Alloc>::PushHeep(ConstReference value)
    {
        LinkType pLast = PushHeepAux(value);
        MaintainUp(pLast);
    }

    template <class Value, class Compare, class Alloc>
    void CMaxHeep<Value, Compare, Alloc>::PopHeep()
    {
        if(Empty())
            return;

        LinkType pLast = PopHeepAux();

        Root()->value = pLast->value;
        DeleteNode(pLast);
        if(!Empty())
            MaintainDown(Root());
        else
            Root() = NULL;
    }

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

    template <class Value, class Compare, class Alloc>
    void CMaxHeep<Value, Compare, Alloc>::Clear()
    {
        if(Empty())
            return;
       
        ClearAux(Root());
        Init();
    }
}

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值