#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