//author:yydrewdrew
#include <iostream>
using namespace std;
template <class T>
struct RBTreeNode
{
T data;
RBTreeNode *parent;
RBTreeNode *left;
RBTreeNode *right;
enum Color{R,B};
Color color;
};
template <class T>
class RBTree
{
public:
void TreeWalk()const;
RBTreeNode<T> *Insert(const T &t);
RBTreeNode<T> *Delete(const T &t);
RBTreeNode<T> *Serach(const T &t)const;
RBTreeNode<T> *Predecesor(const T &t)const;
RBTreeNode<T> *Successor(const T &t)const;
RBTreeNode<T> *Min()const;
RBTreeNode<T> *Max()const;
void Clear();
void Swap(RBTree<T> &obj);
public:
RBTree():root(NULL),NIL(new(RBTreeNode<T>))
{
NIL->data = 0;
NIL->left = NULL;
NIL->right = NULL;
NIL->color = RBTreeNode<T>::B;
}
RBTree<T> &operator = (const RBTree<T> &obj);
RBTree<T>(const RBTree<T> &obj);
virtual ~RBTree();
private:
RBTree(RBTreeNode<T> *r,RBTreeNode<T> *nil):root(r),NIL(nil){}
void LeftRotate(RBTreeNode<T> *const p);
void LeftRotate(const T &t);
void RightRotate(RBTreeNode<T> *const p);
void RightRotate(const T &t);
void RBInsertFixup(RBTreeNode<T> *p);
void RBDeleteFixup(RBTreeNode<T> *p);
void Clean()
{
root = NULL;
NIL = NULL;
}
void Destory(RBTreeNode<T> *p);
void Scan(RBTreeNode<T> *root)const;
void Copy(RBTreeNode<T> *p,const RBTree<T> &obj);
private:
RBTreeNode<T> *root;
RBTreeNode<T> *NIL;
};
template<class T>
void RBTree<T>::Swap(RBTree<T> &obj)
{
std::swap(root,obj.root);
std::swap(NIL,obj.NIL);
return;
}
template<class T>
RBTree<T> &RBTree<T>::operator = (const RBTree<T> &obj)
{
if (this != &obj)
{
Swap(RBTree<T>(obj));
}
return *this;
}
template<class T>
void RBTree<T>::Copy(RBTreeNode<T> *p,const RBTree<T> &obj)
{
if (p != obj.NIL)
{
Copy(p->left,obj);
Insert(p->data);
Copy(p->right,obj);
}
return;
}
///
template<class T>
RBTree<T>::RBTree(const RBTree<T> &obj)
{
root = NULL;
NIL = new RBTreeNode<T>;
NIL->data = 0;
NIL->left = NULL;
NIL->right = NULL;
NIL->color = RBTreeNode<T>::B;
Copy(obj.root,obj);
}
///
template<class T>
void RBTree<T>::Scan(RBTreeNode<T> *root)const
{
if (root == NULL || root == NIL)
{
return;
}
Scan(root->left);
cout<<root->data<<endl;
Scan(root->right);
}
/
template<class T>
void RBTree<T>::TreeWalk()const
{
Scan(root);
}
/
template<class T>
RBTreeNode<T> *RBTree<T>::Min()const
{
if (root == NULL)
{
return NULL;
}
RBTreeNode<T> *p = root;
RBTreeNode<T> *p2 = NULL;
while (p != NIL)
{
p2 = p;
p = p->left;
}
return p2;
}
//
template<class T>
RBTreeNode<T> *RBTree<T>::Max()const
{
if (root == NULL)
{
return NULL;
}
RBTreeNode<T> *p = root;
RBTreeNode<T> *p2 = NULL;
while (p != NIL)
{
p2 = p;
p = p->right;
}
return p2;
}
template<class T>
RBTreeNode<T> *RBTree<T>::Serach(const T &t)const
{
if (root == NULL)
{
return NULL;
}
RBTreeNode<T> *p = root;
while (p != NIL)
{
if (t > p->data)
{
p = p->right;
}
else if (t < p->data)
{
p = p->left;
}
else
{
return p;
}
}
return NULL;
}
/
template<class T>
RBTreeNode<T> *RBTree<T>::Successor(const T &t)const
{
RBTreeNode<T> *p = Serach(t);
if (p->right != NIL)
{
RBTree treetem(p->right,NIL);
p = treetem.Min();
treetem.Clean();
return p;
}
RBTreeNode<T> *p2 = p->parent;
while (p2 != NIL && p == p2->right)
{
p = p2;
p2 = p2->parent;
}
return p2;
}
/
template<class T>
RBTreeNode<T> *RBTree<T>::Predecesor(const T &t)const
{
RBTreeNode<T> *p = Serach(t);
if (p->left != NIL)
{
RBTree<T> treetem(p->left,NIL);
p = treetem.Max();
treetem.Clean();
return p;
}
RBTreeNode<T> *p2 = p->parent;
while (p2 != NIL && p == p2->left)
{
p = p2;
p2 = p2->parent;
}
return p2;
}
template<class T>
void RBTree<T>::LeftRotate(RBTreeNode<T> *const p)
{
if (p == NULL || p == NIL)
{
return;
}
if(p->right == NIL)
{
return;
}
RBTreeNode<T> *p2 = p->right;
p2->parent = p->parent;
if (p->parent != NIL)
{
if (p == p->parent->left)
{
p->parent->left = p2;
}
else
{
p->parent->right = p2;
}
}
if (p2->left != NIL)
{
p2->left->parent = p;
}
p->right = p2->left;
p2->left = p;
p->parent = p2;
return;
}
/
template<class T>
void RBTree<T>::LeftRotate(const T &t)
{
RBTreeNode<T> *p = Serach(t);
LeftRotate(p);
}
template<class T>
void RBTree<T>::RightRotate(RBTreeNode<T> *const p)
{
if (p == NULL || p == NIL)
{
return;
}
if (p->left == NIL)
{
return;
}
RBTreeNode<T> *p2 = p->left;
if (p2->right != NIL)
{
p2->right->parent = p;
}
p->left = p2->right;
p2->parent = p->parent;
if (p->parent != NIL)
{
if (p == p->parent->left)
{
p->parent->left = p2;
}
else
{
p->parent->right = p2;
}
}
p->parent = p2;
p2->right = p;
return;
}
///
template<class T>
void RBTree<T>::RightRotate(const T &t)
{
RBTreeNode<T> *p = Serach(t);
RightRotate(p);
}
///
template<class T>
RBTreeNode<T> *RBTree<T>::Insert(const T &t)
{
RBTreeNode<T> *p = root;
RBTreeNode<T> *p2 = NULL;
while (p != NIL && p != NULL)
{
p2 = p;
if (t > p->data)
{
p = p->right;
}
else
{
p = p->left;
}
}
RBTreeNode<T> *ptem = new RBTreeNode<T>;
ptem->data = t;
ptem->left = NIL;
ptem->right = NIL;
if (p == NULL)
{
root = ptem;
root->color = RBTreeNode<T>::B;
root->parent = NIL;
}
else
{
if (t > p2->data)
{
p2->right = ptem;
ptem->color = RBTreeNode<T>::R;
ptem->parent = p2;
}
else
{
p2->left = ptem;
ptem->color = RBTreeNode<T>::R;
ptem->parent = p2;
}
}
RBInsertFixup(ptem);
return ptem;
}
template<class T>
void RBTree<T>::RBInsertFixup(RBTreeNode<T> *p)
{
while (p->parent->color == RBTreeNode<T>::R)
{
if (p->parent == p->parent->parent->left)
{
RBTreeNode<T> *y = p->parent->parent->right;
if (y->color == RBTreeNode<T>::R)
{
p->color = RBTreeNode<T>::B;
y->color = RBTreeNode<T>::B;
p->parent->parent->color = RBTreeNode<T>::R;
p = p->parent;
}
else if (p == p->parent->right)
{
p = p->parent;
LeftRotate(p);
}
p->parent->color = RBTreeNode<T>::B;
p->parent->parent->color = RBTreeNode<T>::R;
RightRotate(p);
}
else
{
RBTreeNode<T> *y = p->parent->parent->left;
if (y->color == RBTreeNode<T>::R)
{
p->color = RBTreeNode<T>::B;
y->color = RBTreeNode<T>::B;
p->parent->parent->color = RBTreeNode<T>::R;
p = p->parent;
}
else if (p == p->parent->left)
{
p = p->parent;
RightRotate(p);
}
p->parent->color = RBTreeNode<T>::B;
p->parent->parent->color = RBTreeNode<T>::R;
LeftRotate(p);
}
}
root->color = RBTreeNode<T>::B;
return;
}
///
template<class T>
RBTreeNode<T> *RBTree<T>::Delete(const T &t)
{
RBTreeNode<T> *p = Serach(t);
RBTreeNode<T> *p2 = p;
if (p->left != NIL && p->right !=NIL)
{
p2 = Successor(t);
if (p2->parent == NIL)
{
root = p2->right;
p2->right->parent = root;
}
else
{
if (p2 == p2->parent->left)
{
p2->parent->left = p2->right;
}
else
{
p2->parent->right = p2->right;
}
}
p2->right->parent = p2->parent;
swap(p->data,p2->data);
p = p2;
p2 = p2->right;
}
else
{
if (p->left != NIL && p->right == NIL)
{
if (p->parent == NIL)
{
root = p->left;
p->left->parent = NIL;
}
else if (p == p->parent->left)
{
p->parent->left = p->left;
p->left->parent = p->parent;
}
else
{
p->parent->right = p->left;
p->left->parent = p->right;
}
p2 = p->left;
}
else if (p->left == NIL && p->right != NIL)
{
if (p->parent == NIL)
{
root = p->right;
p->right->parent = NIL;
}
else if (p == p->parent->left)
{
p->parent->left = p->right;
p->right->parent = p->parent;
}
else
{
p->parent->right = p->right;
p->right->parent = p->parent;
}
p2 = p->right;
}
else
{
if (p->parent == NIL)
{
root = NULL;
}
else if (p == p->parent->left)
{
p->parent->left = NIL;
}
else
{
p->parent->right = NIL;
}
p2 = p->right;
}
}
if (p->color == RBTreeNode<T>::B)
{
RBDeleteFixup(p2);
}
return p;
}
//
template<class T>
void RBTree<T>::RBDeleteFixup(RBTreeNode<T> *x)
{
if (root == NULL)
{
return;
}
while (x != root && x->color == RBTreeNode<T>::B)
{
if (x == x->parent->left)
{
RBTreeNode<T> *w = x->parent->right;
if (w->color == RBTreeNode<T>::R)
{
w->color = RBTreeNode<T>::B;
LeftRotate(x->parent);
w = x->parent->right;
}
if (w->left->color == RBTreeNode<T>::B && w->right->color == RBTreeNode<T>::B)
{
w->color = RBTreeNode<T>::R;
x = x->parent;
}
else if (w->right->color == RBTreeNode<T>::B)
{
w->left->color = RBTreeNode<T>::B;
w->color = RBTreeNode<T>::R;
RightRotate(w);
w = x->right->right;
w->color = x->parent->color;
x->parent->color = RBTreeNode<T>::B;
w->right->color = RBTreeNode<T>::B;
LeftRotate(x->parent);
x = root;
}
}
else
{
RBTreeNode<T> *w = x->parent->left;
if (w->color == RBTreeNode<T>::R)
{
w->color = RBTreeNode<T>::B;
RightRotate(x->parent);
w = x->parent->left;
}
if (w->right->color == RBTreeNode<T>::B && w->left->color == RBTreeNode<T>::B)
{
w->color = RBTreeNode<T>::R;
x = x->parent;
}
else if (w->left->color == RBTreeNode<T>::B)
{
w->right->color = RBTreeNode<T>::B;
w->color = RBTreeNode<T>::R;
LeftRotate(w);
w = x->parent->left;
w->color = x->parent->color;
x->parent->color = RBTreeNode<T>::B;
w->left->color = RBTreeNode<T>::B;
RightRotate(x->parent);
x = root;
}
}
x->color = RBTreeNode<T>::B;
}
}
template<class T>
void RBTree<T>::Clear()
{
if (root != NULL)
{
Destory(root);
root = NULL;
}
return;
}
//
template<class T>
void RBTree<T>::Destory(RBTreeNode<T> *p)
{
while (p != NIL)
{
Destory(p->left);
Destory(p->right);
delete p;
p = NIL;
}
return;
}
template<class T>
RBTree<T>::~RBTree()
{
Clear();
if (NIL != NULL)
{
delete NIL;
}
}