Implements an efficient ordered data storage.
#include <kmap.h>
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 () | |
KRedBlackTree & | operator= (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. | |
RecordType * | Minimum () |
Find the smallest element in the tree. | |
RecordType const * | Maximum () const |
Find the largest element in the tree. | |
RecordType * | Maximum () |
Find the largest element in the tree. | |
RecordType const * | Find (KeyType const &pKey) const |
Find the key-value pair with key pKey. | |
RecordType * | Find (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. | |
RecordType * | UpperBound (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) |
RecordType * | DuplicateSubTree (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) |
RecordType * | Sibling (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 | |
RecordType * | mRoot |
int | mSize |
AllocatorType | mAllocator |
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_IteratorType<RecordType> IteratorType |
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] |
~KRedBlackTree | ( | ) | [inline] |
KRedBlackTree& operator= | ( | KRedBlackTree< DATA_TYPE, KEY_COMPARE_FUNCTOR, ALLOCATOR > const & | pTree | ) | [inline] |
Deep copy pTree in this.
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.
pRecordCount |
Definition at line 537 of file kmap.h.
{ mAllocator.Reserve(pRecordCount); }
int GetSize | ( | ) | const [inline] |
bool Empty | ( | ) | const [inline] |
KPair<RecordType*, bool> Insert | ( | DataType const & | pData | ) | [inline] |
Insert a new element in the tree.
Takes O(log n) time.
pData | The element to insert. |
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.
pKey | The 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] |
RecordType* Minimum | ( | ) | [inline] |
RecordType const* Maximum | ( | ) | const [inline] |
RecordType* Maximum | ( | ) | [inline] |
RecordType const* Find | ( | KeyType const & | pKey | ) | const [inline] |
Find the key-value pair with key pKey.
Takes O(log n) time.
pKey | The 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.
pKey | The 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.
pKey | The 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.
pKey | The 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] |
bool IsBlack | ( | RecordType const * | pNode | ) | [inline, protected] |
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; } }
RecordType* mRoot [protected] |
int mSize [protected] |
AllocatorType mAllocator [protected] |