#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