Classes | Public Types | Public Member Functions | Protected Member Functions | Protected Attributes

KRedBlackTree< DATA_TYPE, KEY_COMPARE_FUNCTOR, ALLOCATOR > Class Template Reference

Search for all occurrences

Detailed Description

template<typename DATA_TYPE, typename KEY_COMPARE_FUNCTOR, typename ALLOCATOR>
class KRedBlackTree< DATA_TYPE, KEY_COMPARE_FUNCTOR, ALLOCATOR >

Implements an efficient ordered data storage.

Definition at line 259 of file kmap.h.

#include <kmap.h>

List of all members.

Classes

class  RecordType
 This class represents a node in the tree. More...

Public Types

typedef DATA_TYPE DataType
typedef DATA_TYPE::KeyType KeyType
typedef DATA_TYPE::ConstKeyType ConstKeyType
typedef DATA_TYPE::ValueType ValueType
typedef DATA_TYPE::ConstValueType ConstValueType
typedef ALLOCATOR AllocatorType
typedef
RedBack_ConstIteratorType
< RecordType
ConstIteratorType
typedef RedBack_IteratorType
< RecordType
IteratorType

Public Member Functions

 KRedBlackTree ()
 KRedBlackTree (KRedBlackTree const &pTree)
 ~KRedBlackTree ()
KRedBlackTreeoperator= (KRedBlackTree const &pTree)
 Deep copy pTree in this.
bool operator== (KRedBlackTree const &pTree) const
void Reserve (unsigned int pRecordCount)
 Ask ALLOCATOR to reserve space to hold pRecordCount elements.
int GetSize () const
 Get the number of elements in the tree.
bool Empty () const
KPair< RecordType *, bool > Insert (DataType const &pData)
 Insert a new element in the tree.
bool Remove (KeyType const &pKey)
 Remove an element identified by a key from the tree.
void Clear ()
 Remove all elements from the tree.
RecordType const * Minimum () const
 Find the smallest element in the tree.
RecordTypeMinimum ()
 Find the smallest element in the tree.
RecordType const * Maximum () const
 Find the largest element in the tree.
RecordTypeMaximum ()
 Find the largest element in the tree.
RecordType const * Find (KeyType const &pKey) const
 Find the key-value pair with key pKey.
RecordTypeFind (KeyType const &pKey)
 Find the key-value pair with key pKey.
RecordType const * UpperBound (KeyType const &pKey) const
 Find the key-value pair with the smallest key greater than pKey.
RecordTypeUpperBound (KeyType const &pKey)
 Find the key-value pair with the smallest key greater than pKey.

Protected Member Functions

void IsSane ()
 Sanity check on the tree.
void IsSubTreeSane (RecordType const *pNode) const
void ComputeBlackDepth (RecordType *pNode, unsigned int pDepth)
void CheckLeavesBlackDepth (RecordType *pNode, unsigned int pBlackDepth)
RecordTypeDuplicateSubTree (RecordType const *pNode)
void FixNodesAfterInsertion (RecordType *pNode)
void LeftRotate (RecordType *pNode)
void RightRotate (RecordType *pNode)
void RemoveNode (RecordType *pNode)
void ReplaceNode (RecordType *pNodeToReplace, RecordType *pReplacement)
RecordTypeSibling (RecordType const *pParent, RecordType const *pNode) const
bool IsBlack (RecordType const *pNode)
void FixNodesAfterRemoval (RecordType *pParent, RecordType *pNode)
void ClearSubTree (RecordType *pNode)
int GetSubTreeSize (RecordType *pNode) const

Protected Attributes

RecordTypemRoot
int mSize
AllocatorType mAllocator

Member Typedef Documentation

typedef DATA_TYPE DataType

Definition at line 262 of file kmap.h.

typedef DATA_TYPE::KeyType KeyType

Definition at line 263 of file kmap.h.

typedef DATA_TYPE::ConstKeyType ConstKeyType

Definition at line 264 of file kmap.h.

typedef DATA_TYPE::ValueType ValueType

Definition at line 265 of file kmap.h.

typedef DATA_TYPE::ConstValueType ConstValueType

Definition at line 266 of file kmap.h.

typedef ALLOCATOR AllocatorType

Definition at line 267 of file kmap.h.

Definition at line 453 of file kmap.h.

Definition at line 454 of file kmap.h.


Constructor & Destructor Documentation

KRedBlackTree ( ) [inline]

Definition at line 457 of file kmap.h.

: mRoot(0), mSize(0), mAllocator(sizeof(RecordType)) {}
KRedBlackTree ( KRedBlackTree< DATA_TYPE, KEY_COMPARE_FUNCTOR, ALLOCATOR > const &  pTree) [inline]

Definition at line 458 of file kmap.h.

: mRoot(0), mSize(0), mAllocator(sizeof(RecordType)) { operator=(pTree); }
~KRedBlackTree ( ) [inline]

Definition at line 459 of file kmap.h.

{ Clear(); }

Member Function Documentation

KRedBlackTree& operator= ( KRedBlackTree< DATA_TYPE, KEY_COMPARE_FUNCTOR, ALLOCATOR > const &  pTree) [inline]

Deep copy pTree in this.

Parameters:
pTree

Definition at line 464 of file kmap.h.

    {
        if( this != &pTree )
        {
            Clear();

            mAllocator = pTree.mAllocator;

            if( pTree.mRoot )
            {
                void* lBuffer = mAllocator.AllocateRecords();
                #if ( defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
                    #pragma push_macro("new")
                    #undef new
                #endif
                mRoot = new(lBuffer) RecordType(*(pTree.mRoot));
                #if ( defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
                    #pragma pop_macro("new")
                #endif
                mRoot->mLeftChild = DuplicateSubTree(pTree.mRoot->mLeftChild);
                mRoot->mRightChild = DuplicateSubTree(pTree.mRoot->mRightChild);

                if (mRoot->mLeftChild)
                {
                    mRoot->mLeftChild->mParent = mRoot;
                }

                if (mRoot->mRightChild)
                {
                    mRoot->mRightChild->mParent = mRoot;
                }
            }
            else
            {
                K_ASSERT( pTree.mSize == 0 );
                K_ASSERT( mRoot == 0 );
            }

            mSize = pTree.mSize;
        }

        return *this;
    }
bool operator== ( KRedBlackTree< DATA_TYPE, KEY_COMPARE_FUNCTOR, ALLOCATOR > const &  pTree) const [inline]

Definition at line 508 of file kmap.h.

    {
        // Check a few quick shortcuts
        if( this == &pTree )
            return true;

        if( GetSize() != pTree.GetSize() )
            return false;

        // Iterator through all nodes; if we reach the end of both iterators at the same
        // time then we have two iterators that match.
        ConstIteratorType End;
        ConstIteratorType Iter1(Minimum());
        ConstIteratorType Iter2(pTree.Minimum());

        while( (Iter1 != End) && (Iter2 != End) &&
               (Iter1->GetKey() == Iter2->GetKey()) &&
               (Iter1->GetValue() == Iter2->GetValue()) )
        {
            ++Iter1;
            ++Iter2;
        }

        return Iter1 == End && Iter2 == End;
    }
void Reserve ( unsigned int  pRecordCount) [inline]

Ask ALLOCATOR to reserve space to hold pRecordCount elements.

Parameters:
pRecordCount

Definition at line 537 of file kmap.h.

    {
        mAllocator.Reserve(pRecordCount);
    }
int GetSize ( ) const [inline]

Get the number of elements in the tree.

Takes O(1) time.

Returns:
The number of elements in the tree.

Definition at line 545 of file kmap.h.

{ return mSize; }
bool Empty ( ) const [inline]

Definition at line 547 of file kmap.h.

{ return mSize == 0; }
KPair<RecordType*, bool> Insert ( DataType const &  pData) [inline]

Insert a new element in the tree.

Takes O(log n) time.

Parameters:
pDataThe element to insert.
Returns:
If pData.GetKey() is already present in the tree, returns the existing record and false; else returns the new record and true.

Definition at line 554 of file kmap.h.

    {
        KEY_COMPARE_FUNCTOR lCompareKeys;
        bool lResult = false;
        RecordType* lParent = 0;
        RecordType* lNode = mRoot;
        while (lNode != 0)
        {
            KeyType const& lNodeKey = lNode->GetKey();
            KeyType const& lDataKey = pData.GetKey();

            if (lCompareKeys(lNodeKey, lDataKey) < 0)
            {
                lParent = lNode;
                lNode = lNode->mRightChild;
            }
            else if (lCompareKeys(lNodeKey, lDataKey) > 0)
            {
                lParent = lNode;
                lNode = lNode->mLeftChild;
            }
            else
            {
                break;
            }
        }

        if (lNode == 0)
        {
            void* lBuffer = mAllocator.AllocateRecords();
            #if ( defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
                #pragma push_macro("new")
                #undef new
            #endif
            lNode = new(lBuffer) RecordType(pData);
            #if ( defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
                #pragma pop_macro("new")
            #endif
            mSize++;

            #if ( !defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
                K_ASSERT(lNode == lBuffer);
            #endif

            if (lParent)
            {
                if (lCompareKeys(lParent->GetKey(), pData.GetKey()) < 0)
                {
                    K_ASSERT(lParent->mRightChild == 0);
                    lParent->mRightChild = lNode;
                    lNode->mParent = lParent;
                }
                else
                {
                    K_ASSERT(lParent->mLeftChild == 0);
                    lParent->mLeftChild = lNode;
                    lNode->mParent = lParent;
                }
            }
            else
            {
                mRoot = lNode;
            }

            // Fix red black tree property
            FixNodesAfterInsertion(lNode);

            lResult = true;
        }

#ifdef SANITY_CHECK
        IsSane();
#endif

        return KPair<RecordType*, bool>(lNode, lResult);
    }
bool Remove ( KeyType const &  pKey) [inline]

Remove an element identified by a key from the tree.

Takes O(log n) time.

Parameters:
pKeyThe key identifying the element to remove.

Definition at line 634 of file kmap.h.

    {
        KEY_COMPARE_FUNCTOR lCompareKeys;
        bool lResult = false;
        RecordType* lNode = mRoot;
        while (lNode != 0)
        {
            if (lCompareKeys(lNode->GetKey(), pKey) < 0)
            {
                lNode = lNode->mRightChild;
            }
            else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
            {
                lNode = lNode->mLeftChild;
            }
            else
            {
                break;
            }
        }

        if (lNode)
        {
            RemoveNode(lNode);
            mSize--;
            lNode->~RecordType();
            mAllocator.FreeMemory(lNode);

            lResult = true;
        }

#ifdef SANITY_CHECK
        IsSane();
#endif

        return lResult;
    }
void Clear ( ) [inline]

Remove all elements from the tree.

Takes O(n) time. Recursive.

Definition at line 674 of file kmap.h.

    {
        if (mRoot)
        {
            ClearSubTree(mRoot->mLeftChild);
            ClearSubTree(mRoot->mRightChild);
            mRoot->~RecordType();
            mAllocator.FreeMemory(mRoot);
            mRoot = 0;
            mSize = 0;
        }
    }
RecordType const* Minimum ( ) const [inline]

Find the smallest element in the tree.

Takes O(log n) time.

Definition at line 690 of file kmap.h.

    {
        if (0 != mRoot)
        {
            return mRoot->Minimum();
        }
        else
        {
            return 0;
        }
    }
RecordType* Minimum ( ) [inline]

Find the smallest element in the tree.

Takes O(log n) time.

Definition at line 705 of file kmap.h.

    {
        if (0 != mRoot)
        {
            return mRoot->Minimum();
        }
        else
        {
            return 0;
        }
    }
RecordType const* Maximum ( ) const [inline]

Find the largest element in the tree.

Takes O(log n) time.

Definition at line 720 of file kmap.h.

    {
        if (0 != mRoot)
        {
            return mRoot->Maximum();
        }
        else
        {
            return 0;
        }
    }
RecordType* Maximum ( ) [inline]

Find the largest element in the tree.

Takes O(log n) time.

Definition at line 735 of file kmap.h.

    {
        if (0 != mRoot)
        {
            return mRoot->Maximum();
        }
        else
        {
            return 0;
        }
    }
RecordType const* Find ( KeyType const &  pKey) const [inline]

Find the key-value pair with key pKey.

Takes O(log n) time.

Parameters:
pKeyThe key to look for.

Definition at line 751 of file kmap.h.

    {
        KEY_COMPARE_FUNCTOR lCompareKeys;
        RecordType const* lNode = mRoot;
        while (lNode != 0)
        {
            if (lCompareKeys(lNode->GetKey(), pKey) < 0)
            {
                lNode = lNode->mRightChild;
            }
            else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
            {
                lNode = lNode->mLeftChild;
            }
            else
            {
                break;
            }
        }

        return lNode;
    }
RecordType* Find ( KeyType const &  pKey) [inline]

Find the key-value pair with key pKey.

Takes O(log n) time.

Parameters:
pKeyThe key to look for.

Definition at line 778 of file kmap.h.

    {
        KEY_COMPARE_FUNCTOR lCompareKeys;
        RecordType* lNode = mRoot;
        while (lNode != 0)
        {
            if (lCompareKeys(lNode->GetKey(), pKey) < 0)
            {
                lNode = lNode->mRightChild;
            }
            else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
            {
                lNode = lNode->mLeftChild;
            }
            else
            {
                break;
            }
        }

        return lNode;
    }
RecordType const* UpperBound ( KeyType const &  pKey) const [inline]

Find the key-value pair with the smallest key greater than pKey.

Takes O(log n) time.

Parameters:
pKeyThe key to look for.

Definition at line 805 of file kmap.h.

    {
        KEY_COMPARE_FUNCTOR lCompareKeys;
        RecordType const* lNode = mRoot;
        RecordType const* lCandidate = 0;
        while (lNode != 0)
        {
            if (lCompareKeys(lNode->GetKey(), pKey) <= 0)
            {
                lNode = lNode->mRightChild;
            }
            else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
            {
                lCandidate = lNode;
                lNode = lNode->mLeftChild;
            }
        }
        
        return lCandidate;
    }
RecordType* UpperBound ( KeyType const &  pKey) [inline]

Find the key-value pair with the smallest key greater than pKey.

Takes O(log n) time.

Parameters:
pKeyThe key to look for.

Definition at line 830 of file kmap.h.

    {
        KEY_COMPARE_FUNCTOR lCompareKeys;
        RecordType* lNode = mRoot;
        RecordType* lCandidate = 0;
        while (lNode != 0)
        {
            if (lCompareKeys(lNode->GetKey(), pKey) <= 0)
            {
                lNode = lNode->mRightChild;
            }
            else if (lCompareKeys(lNode->GetKey(), pKey) > 0)
            {
                lCandidate = lNode;
                lNode = lNode->mLeftChild;
            }
        }
        
        return lCandidate;
    }
void IsSane ( ) [inline, protected]

Sanity check on the tree.

Check if all red-black tree properties hold. Also check if all key-values pairs are ordered properly.

Definition at line 861 of file kmap.h.

    {
        K_ASSERT((mRoot == 0) || (mRoot->mColor == RecordType::eBlack));
        K_ASSERT(((mRoot == 0) && (mSize == 0)) || (mRoot != 0) && (mSize != 0));
        IsSubTreeSane(mRoot);

        ComputeBlackDepth(mRoot, 0);

        RecordType* lNode = mRoot;
        unsigned int lLeafBlackDepth = 0;
        while (lNode)
        {
            if (lNode->mLeftChild == 0)
            {
                lLeafBlackDepth = lNode->mBlackDepth + ((lNode->mColor == RecordType::eBlack) ? 1 : 0);
            }

            lNode = lNode->mLeftChild;
        }

        CheckLeavesBlackDepth(mRoot, lLeafBlackDepth);
    }
void IsSubTreeSane ( RecordType const *  pNode) const [inline, protected]

Definition at line 884 of file kmap.h.

    {
        KEY_COMPARE_FUNCTOR lCompareKeys;

        if (pNode)
        {
            K_ASSERT(pNode != pNode->mParent);
            K_ASSERT(pNode != pNode->mLeftChild);
            K_ASSERT(pNode != pNode->mRightChild);

            // Check for two consecutive red nodes
            K_ASSERT((pNode->mColor == RecordType::eBlack) ||
                     (pNode->mLeftChild == NULL) ||
                     (pNode->mLeftChild->mColor == RecordType::eBlack));

            K_ASSERT((pNode->mColor == RecordType::eBlack) ||
                     (pNode->mRightChild == NULL) ||
                     (pNode->mRightChild->mColor == RecordType::eBlack));

            // Check key ordering
            K_ASSERT((pNode->mLeftChild == 0 ||
                      lCompareKeys(pNode->GetKey(), pNode->mLeftChild->GetKey()) > 0));

            K_ASSERT((pNode->mRightChild == 0 ||
                      lCompareKeys(pNode->GetKey(), pNode->mRightChild->GetKey()) < 0));

            IsSubTreeSane(pNode->mLeftChild);
            IsSubTreeSane(pNode->mRightChild);
        }
    }
void ComputeBlackDepth ( RecordType pNode,
unsigned int  pDepth 
) [inline, protected]

Definition at line 915 of file kmap.h.

    {
        if (pNode)
        {
            pNode->mBlackDepth = pDepth;
            if (pNode->mColor == RecordType::eBlack)
            {
                pDepth++;
            }

            ComputeBlackDepth(pNode->mLeftChild, pDepth);
            ComputeBlackDepth(pNode->mRightChild, pDepth);
        }
    }
void CheckLeavesBlackDepth ( RecordType pNode,
unsigned int  pBlackDepth 
) [inline, protected]

Definition at line 930 of file kmap.h.

    {
        if (pNode)
        {
            if ((pNode->mLeftChild == 0) || pNode->mRightChild == 0)
            {
                int lBlackDepth = pNode->mBlackDepth + ((pNode->mColor == RecordType::eBlack) ? 1 : 0);
                K_ASSERT(lBlackDepth == pBlackDepth);
            }

            CheckLeavesBlackDepth(pNode->mLeftChild, pBlackDepth);
            CheckLeavesBlackDepth(pNode->mRightChild, pBlackDepth);
        }
    }
RecordType* DuplicateSubTree ( RecordType const *  pNode) [inline, protected]

Definition at line 945 of file kmap.h.

    {
        RecordType* lNewSubTree = 0;

        if (pNode)
        {
            void* lBuffer = mAllocator.AllocateRecords();
            #if ( defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
                #pragma push_macro("new")
                #undef new
            #endif
            lNewSubTree = new(lBuffer) RecordType(*pNode);
            #if ( defined(MEMORY_DEBUG) && defined(_DEBUG) && defined(KARCH_ENV_WIN32))
                #pragma pop_macro("new")
            #endif
            lNewSubTree->mLeftChild = DuplicateSubTree(pNode->mLeftChild);
            lNewSubTree->mRightChild = DuplicateSubTree(pNode->mRightChild);

            if (lNewSubTree->mLeftChild)
            {
                lNewSubTree->mLeftChild->mParent = lNewSubTree;
            }

            if (lNewSubTree->mRightChild)
            {
                lNewSubTree->mRightChild->mParent = lNewSubTree;
            }
        }

        return lNewSubTree;
    }
void FixNodesAfterInsertion ( RecordType pNode) [inline, protected]

Definition at line 977 of file kmap.h.

    {
        RecordType* lNode = pNode;
        bool lDone = false;

        while (!lDone)
        {
            lDone = true;

            if (lNode->mParent == 0)
            {
                lNode->mColor = RecordType::eBlack;
            }
            else if (lNode->mParent->mColor == RecordType::eRed)
            {
                RecordType* lUncle = 0;
                if (lNode->mParent == lNode->mParent->mParent->mLeftChild)
                {
                    lUncle = lNode->mParent->mParent->mRightChild;
                }
                else if (lNode->mParent == lNode->mParent->mParent->mRightChild)
                {
                    lUncle = lNode->mParent->mParent->mLeftChild;
                }

                // since lNode->mParent is red, lNode->mParent->mParent exists

                if (lUncle && lUncle->mColor == RecordType::eRed)
                {
                    lNode->mParent->mColor = RecordType::eBlack;
                    lUncle->mColor = RecordType::eBlack;
                    lNode->mParent->mParent->mColor = RecordType::eRed;
                    lNode = lNode->mParent->mParent;

                    lDone = false;
                }
                else
                {
                    if ((lNode == lNode->mParent->mRightChild) &&
                        (lNode->mParent == lNode->mParent->mParent->mLeftChild))
                    {
                        LeftRotate(lNode->mParent);
                        lNode = lNode->mLeftChild;
                    }
                    else if ((lNode == lNode->mParent->mLeftChild) &&
                            (lNode->mParent == lNode->mParent->mParent->mRightChild))
                    {
                        RightRotate(lNode->mParent);
                        lNode = lNode->mRightChild;
                    }

                    lNode->mParent->mColor = RecordType::eBlack;
                    lNode->mParent->mParent->mColor = RecordType::eRed;
                    if ((lNode == lNode->mParent->mLeftChild) &&
                        (lNode->mParent == lNode->mParent->mParent->mLeftChild))
                    {
                        RightRotate(lNode->mParent->mParent);
                    }
                    else
                    {
                        LeftRotate(lNode->mParent->mParent);
                    }
                }
            }
        }

        mRoot->mColor = RecordType::eBlack;
    }
void LeftRotate ( RecordType pNode) [inline, protected]

Definition at line 1046 of file kmap.h.

    {
        RecordType* lNode = pNode->mRightChild;

#ifdef _DEBUG
        RecordType* A = pNode->mLeftChild;
        RecordType* B = lNode->mLeftChild;
        RecordType* C = lNode->mRightChild;
        RecordType* Z = pNode->mParent;
#endif

        pNode->mRightChild = lNode->mLeftChild;
        if (pNode->mRightChild)
        {
            pNode->mRightChild->mParent = pNode;
        }

        lNode->mParent = pNode->mParent;
        if (pNode->mParent == 0)
        {
            K_ASSERT(mRoot == pNode);
            mRoot = lNode;
        }
        else if (pNode == pNode->mParent->mLeftChild)
        {
            pNode->mParent->mLeftChild = lNode;
        }
        else
        {
            pNode->mParent->mRightChild = lNode;
        }
        pNode->mParent = lNode;
        lNode->mLeftChild = pNode;

        K_ASSERT(pNode->mLeftChild == A);
        K_ASSERT(pNode->mRightChild == B);
        K_ASSERT(pNode->mParent == lNode);

        K_ASSERT(lNode->mLeftChild == pNode);
        K_ASSERT(lNode->mRightChild == C);
        K_ASSERT(lNode->mParent == Z);

        K_ASSERT(A == 0 || A->mParent == pNode);
        K_ASSERT(B == 0 || B->mParent == pNode);
        K_ASSERT(C == 0 || C->mParent == lNode);
        K_ASSERT(Z == 0 || Z->mLeftChild == lNode || Z->mRightChild == lNode);
    }
void RightRotate ( RecordType pNode) [inline, protected]

Definition at line 1095 of file kmap.h.

    {
        RecordType* lNode = pNode->mLeftChild;

#ifdef _DEBUG
        RecordType* A = lNode->mLeftChild;
        RecordType* B = lNode->mRightChild;
        RecordType* C = pNode->mRightChild;
        RecordType* Z = pNode->mParent;
#endif

        pNode->mLeftChild = lNode->mRightChild;
        if (pNode->mLeftChild)
        {
            pNode->mLeftChild->mParent = pNode;
        }

        lNode->mParent = pNode->mParent;
        if (pNode->mParent == 0)
        {
            K_ASSERT(mRoot == pNode);
            mRoot = lNode;
        }
        else if (pNode == pNode->mParent->mRightChild)
        {
            pNode->mParent->mRightChild = lNode;
        }
        else
        {
            pNode->mParent->mLeftChild = lNode;
        }
        pNode->mParent = lNode;
        lNode->mRightChild = pNode;

        K_ASSERT(lNode->mLeftChild == A);
        K_ASSERT(lNode->mRightChild == pNode);
        K_ASSERT(lNode->mParent == Z);

        K_ASSERT(pNode->mLeftChild == B);
        K_ASSERT(pNode->mRightChild == C);
        K_ASSERT(pNode->mParent == lNode);

        K_ASSERT(A == 0 || A->mParent == lNode);
        K_ASSERT(B == 0 || B->mParent == pNode);
        K_ASSERT(C == 0 || C->mParent == pNode);
        K_ASSERT(Z == 0 || Z->mLeftChild == lNode || Z->mRightChild == lNode);
    }
void RemoveNode ( RecordType pNode) [inline, protected]

Definition at line 1144 of file kmap.h.

    {
        if (pNode->mLeftChild == 0)
        {
            if (pNode->mRightChild == 0)
            {
                if (pNode->mParent)
                {
                    if (pNode->mParent->mLeftChild == pNode)
                    {
                        pNode->mParent->mLeftChild = 0;
                    }
                    else if (pNode->mParent->mRightChild == pNode)
                    {
                        pNode->mParent->mRightChild = 0;
                    }
                    else
                    {
                        K_ASSERT_MSG_NOW("Node not found in KRedBlackTree");
                    }
                }
                else
                {
                    K_ASSERT(mRoot == pNode);
                    mRoot = 0;
                }

                if (pNode->mColor == RecordType::eBlack)
                {
                    FixNodesAfterRemoval(pNode->mParent, 0);
                }
            }
            else
            {
                if (pNode->mParent)
                {
                    if (pNode->mParent->mLeftChild == pNode)
                    {
                        pNode->mParent->mLeftChild = pNode->mRightChild;
                        pNode->mRightChild->mParent = pNode->mParent;
                    }
                    else if (pNode->mParent->mRightChild == pNode)
                    {
                        pNode->mParent->mRightChild = pNode->mRightChild;
                        pNode->mRightChild->mParent = pNode->mParent;
                    }
                    else
                    {
                        K_ASSERT_MSG_NOW("Node not found in KRedBlackTree");
                    }
                }
                else
                {
                    K_ASSERT(mRoot == pNode);
                    mRoot = pNode->mRightChild;
                    pNode->mRightChild->mParent = 0;
                }

                if (pNode->mColor == RecordType::eBlack)
                {
                    FixNodesAfterRemoval(pNode->mRightChild->mParent, pNode->mRightChild);
                }
            }
        }
        else
        {
            if (pNode->mRightChild == 0)
            {
                if (pNode->mParent)
                {
                    if (pNode->mParent->mLeftChild == pNode)
                    {
                        pNode->mParent->mLeftChild = pNode->mLeftChild;
                        pNode->mLeftChild->mParent = pNode->mParent;
                    }
                    else if (pNode->mParent->mRightChild == pNode)
                    {
                        pNode->mParent->mRightChild = pNode->mLeftChild;
                        pNode->mLeftChild->mParent = pNode->mParent;
                    }
                    else
                    {
                        K_ASSERT_MSG_NOW("Node not found in KRedBlackTree");
                    }
                }
                else
                {
                    K_ASSERT(mRoot == pNode);
                    mRoot = pNode->mLeftChild;
                    pNode->mLeftChild->mParent = 0;
                }

                if (pNode->mColor == RecordType::eBlack)
                {
                    FixNodesAfterRemoval(pNode->mLeftChild->mParent, pNode->mLeftChild);
                }
            }
            else
            {
                RecordType* lMinRightNode = pNode->mRightChild->Minimum();
                RemoveNode(lMinRightNode);

                lMinRightNode->mColor = pNode->mColor;
                ReplaceNode(pNode, lMinRightNode);
            }
        }

        pNode->mParent = 0;
        pNode->mLeftChild = 0;
        pNode->mRightChild = 0;
    }
void ReplaceNode ( RecordType pNodeToReplace,
RecordType pReplacement 
) [inline, protected]

Definition at line 1257 of file kmap.h.

    {
        pReplacement->mParent = pNodeToReplace->mParent;
        if (pNodeToReplace->mParent)
        {
            if (pNodeToReplace->mParent->mLeftChild == pNodeToReplace)
            {
                pNodeToReplace->mParent->mLeftChild = pReplacement;
            }
            else if (pNodeToReplace->mParent->mRightChild == pNodeToReplace)
            {
                pNodeToReplace->mParent->mRightChild = pReplacement;
            }
        }
        else
        {
            K_ASSERT(mRoot == pNodeToReplace);
            mRoot = pReplacement;
        }

        pReplacement->mLeftChild = pNodeToReplace->mLeftChild;
        if (pReplacement->mLeftChild)
        {
            pReplacement->mLeftChild->mParent = pReplacement;
        }

        pReplacement->mRightChild = pNodeToReplace->mRightChild;
        if (pReplacement->mRightChild)
        {
            pReplacement->mRightChild->mParent = pReplacement;
        }
    }
RecordType* Sibling ( RecordType const *  pParent,
RecordType const *  pNode 
) const [inline, protected]

Definition at line 1290 of file kmap.h.

    {
        if (pParent)
        {
            if (pParent->mLeftChild == pNode)
            {
                return pParent->mRightChild;
            }
            else if (pParent->mRightChild == pNode)
            {
                return pParent->mLeftChild;
            }
        }

        return 0;
    }
bool IsBlack ( RecordType const *  pNode) [inline, protected]

Definition at line 1307 of file kmap.h.

    {
        return ((pNode == 0) || (pNode->mColor == RecordType::eBlack));
    }
void FixNodesAfterRemoval ( RecordType pParent,
RecordType pNode 
) [inline, protected]

Definition at line 1312 of file kmap.h.

    {
        RecordType* lParent = pParent;
        RecordType* lNode = pNode;
        bool lDone = false;

        while (!lDone)
        {
            lDone = true;

            if (!IsBlack(lNode))
            {
                lNode->mColor = RecordType::eBlack;
            }
            else if (lParent != NULL)
            {
                RecordType* lSibling = Sibling(lParent, lNode);

                if (!IsBlack(lSibling))
                {
                    lParent->mColor = RecordType::eRed;
                    lSibling->mColor = RecordType::eBlack;
                    if (lNode == lParent->mLeftChild)
                    {
                        LeftRotate(lParent);
                    }
                    else
                    {
                        RightRotate(lParent);
                    }

                    // update sibling: it may have change after rotation
                    // parent was not affected by this rotation
                    lSibling = Sibling(lParent, lNode);
                }

                /* check this for null sibling */
                if (lSibling &&
                    IsBlack(lParent) &&
                    IsBlack(lSibling) &&
                    IsBlack(lSibling->mLeftChild) &&
                    IsBlack(lSibling->mRightChild))
                {
                    lSibling->mColor = RecordType::eRed;
                    lNode = lParent;
                    lParent = lParent->mParent;
                    lDone = false;
                }
                else
                {
                    if (!IsBlack(lParent) &&
                        IsBlack(lSibling) &&
                        ((lSibling == 0) || IsBlack(lSibling->mLeftChild)) &&
                        ((lSibling == 0) || IsBlack(lSibling->mRightChild)))
                    {
                        if (lSibling)
                        {
                            lSibling->mColor = RecordType::eRed;
                        }
                        lParent->mColor = RecordType::eBlack;
                    }
                    else // lSibling != 0
                    {
                        if ((lNode == lParent->mLeftChild) &&
                            IsBlack(lSibling) &&
                            !IsBlack(lSibling->mLeftChild) &&
                            IsBlack(lSibling->mRightChild))
                        {
                            lSibling->mColor = RecordType::eRed;
                            lSibling->mLeftChild->mColor = RecordType::eBlack;
                            RightRotate(lSibling);
                        }
                        else if ((lNode == lParent->mRightChild) &&
                                 IsBlack(lSibling) &&
                                 IsBlack(lSibling->mLeftChild) &&
                                 !IsBlack(lSibling->mRightChild))
                        {
                            lSibling->mColor = RecordType::eRed;
                            lSibling->mRightChild->mColor = RecordType::eBlack;
                            LeftRotate(lSibling);
                        }

                        // update sibling: it may have change after rotation
                        lSibling = Sibling(lParent, lNode);
                        K_ASSERT(lSibling != 0); // lSibling is now
                                                 // the former red
                                                 // child of the
                                                 // former sibling

                        lSibling->mColor = lParent->mColor;
                        lParent->mColor = RecordType::eBlack;
                        if (lNode == lParent->mLeftChild)
                        {
                            if (lSibling->mRightChild)
                            {
                                lSibling->mRightChild->mColor = RecordType::eBlack;
                            }
                            LeftRotate(lParent);
                        }
                        else
                        {
                            if (lSibling->mLeftChild)
                            {
                                lSibling->mLeftChild->mColor = RecordType::eBlack;
                            }
                            RightRotate(lParent);
                        }
                    }
                }
            }
        }

        if (mRoot)
        {
            mRoot->mColor = RecordType::eBlack;
        }
    }
void ClearSubTree ( RecordType pNode) [inline, protected]

Definition at line 1431 of file kmap.h.

    {
        if (pNode)
        {
            ClearSubTree(pNode->mLeftChild);
            ClearSubTree(pNode->mRightChild);
            pNode->~RecordType();
            mAllocator.FreeMemory(pNode);
        }
    }
int GetSubTreeSize ( RecordType pNode) const [inline, protected]

Definition at line 1442 of file kmap.h.

    {
        if (pNode)
        {
            return GetSubTreeSize(pNode->mLeftChild) + GetSubTreeSize(pNode->mRightChild) + 1;
        }
        else
        {
            return 0;
        }
    }

Member Data Documentation

RecordType* mRoot [protected]

Definition at line 852 of file kmap.h.

int mSize [protected]

Definition at line 853 of file kmap.h.

Definition at line 855 of file kmap.h.


The documentation for this class was generated from the following file: