#include <iostream>
using namespace std;
typedef enum col{RED, BLACK} col;
template <class T>
class RBNode
{
public:
RBNode(T k, RBNode<T>* l=NULL, RBNode<T>* r=NULL, RBNode<T>* p=NULL):
key(k), left(l), right(r), parent(p) {}
~RBNode();
T key;
RBNode<T>* left, *right, *parent;
col color;
};
template <class T>
class RBTree
{
public:
RBTree(RBNode<T>* r=NULL): root(r)
{
NIL=new RBNode<T>(-1);
NIL->color=BLACK;
root->color=BLACK;
root->left=NIL;
root->right=NIL;
root->parent=NIL;
}
~RBTree();
void inorder(RBNode<T> *);
RBNode<T>* search(T k, RBNode<T> *x);
RBNode<T>* min(RBNode<T> *x);
RBNode<T>* max(RBNode<T> *x);
RBNode<T>* successor(RBNode<T> *x);
void rightRotate(RBNode<T> *z);
void leftRotate(RBNode<T> *z);
void Insert(RBNode<T> *z);
void RBInsertFixup(RBNode<T> *x);
void Delete(RBNode<T> *z);
void Delete_fixup(RBNode<T> *x);
RBNode<T> *root;
RBNode<T> *NIL;
};
template <class T>
void RBTree<T>::inorder(RBNode<T>* x)
{
if(x==NIL)
return;
inorder(x->left);
cout<<x->key<<" ";
inorder(x->right);
}
template <class T>
RBNode<T>* RBTree<T>::search(T k, RBNode<T>* x)
{
RBNode<T>* p=x;
while(p!=NIL && p->key!=k)
{
if(k<p->key)
p=p->left;
else
p=p->right;
}
return p;
}
template <class T>
RBNode<T>* RBTree<T>::min(RBNode<T> *x)
{
RBNode<T>* p=x;
if(p==NIL)
return NIL;
while(p->left!=NIL)
p=p->left;
return p;
}
template <class T>
RBNode<T>* RBTree<T>::max(RBNode<T> *x)
{
RBNode<T> *p=x;
if(p==NIL)
return NIL;
while(p->right!=NIL)
p=p->right;
return p;
}
template <class T>
RBNode<T>* RBTree<T>::successor(RBNode<T> *x)
{
if(x->right!=NIL)
return min(x->right);
RBNode<T>* y=x;
RBNode<T>* p=x->parent;
while(p!=NIL && p->right==y)
{
y=p;
p=p->parent;
}
return p;
}
template <class T>
void RBTree<T>::leftRotate(RBNode<T> *z)
{
RBNode<T>* y=z->right;
z->right=y->left;
if(y->left!=NIL)
y->left->parent=z;
y->parent=z->parent;
if(z->parent==NIL)
root=y;
else if(z==z->parent->left)
z->parent->left=y;
else
z->parent->right=y;
z->parent=y;
y->left=z;
}
template <class T>
void RBTree<T>::rightRotate(RBNode<T> *z)
{
RBNode<T> *y=z->left;
z->left=y->right;
if(y->right!=NIL)
y->right->parent=z;
y->parent=z->parent;
if(z->parent==NIL)
root=y;
else if(z==z->parent->left)
z->parent->left=y;
else
z->parent->right=y;
y->right=z;
z->parent=y;
}
template <class T>
void RBTree<T>::Insert(RBNode<T> *z)
{
RBNode<T>* y=root;
RBNode<T>* x=NIL;
while(y!=NIL)
{
x=y;
if(z->key<y->key)
y=y->left;
else
y=y->right;
}
z->parent=x;
if(x==NIL)
root=z;
else if(z->key<x->key)
x->left=z;
else
x->right=z;
z->color=RED;
z->left=NIL;
z->right=NIL;
RBInsertFixup(z);
}
template <class T>
void RBTree<T>::RBInsertFixup(RBNode<T> *z)
{
RBNode<T>* x=z;
RBNode<T>* w;
while(x->parent->color==RED)
{
if(x->parent==x->parent->parent->left)
{
w=x->parent->parent->right;
if(w->color==RED) //case 1
{
w->color=BLACK;
x->parent->color=BLACK;
x->parent->parent->color=RED;
x=x->parent->parent;
}
else
{
if(x==x->parent->right) //case 2
{
x=x->parent;
leftRotate(x);
}
x->parent->color=BLACK; //case 3
x->parent->parent->color=RED;
rightRotate(x->parent->parent);
}
}
else
{
w=x->parent->parent->left;
if(w->color==RED)
{
w->color=BLACK;
x->parent->color=BLACK;
x->parent->parent->color=RED;
x=x->parent->parent;
}
else
{
if(x==x->parent->left)
{
x=x->parent;
rightRotate(x);
}
x->parent->color=BLACK;
x->parent->parent->color=RED;
leftRotate(x->parent->parent);
}
}
}
root->color=BLACK;
}
template <class T>
void RBTree<T>::Delete(RBNode<T> *z)
{
RBNode<T> *y;
RBNode<T> *x;
if(z->left==NIL || z->right==NIL)
y=z;
else
y=successor(z);
if(y->left!=NIL)
x=y->left;
else
x=y->right;
x->parent=y->parent;
if(y->parent==NIL)
root=x;
else if(y==y->parent->left)
y->parent->left=x;
else
y->parent->right=x;
if(y!=z)
z->key=y->key;
if(y->color==BLACK)
Delete_fixup(x);
}
template <class T>
void RBTree<T>::Delete_fixup(RBNode<T> *z)
{
RBNode<T> *x=z;
RBNode<T> *w;
while(x->color==BLACK && x!=root)
{
if(x==x->parent->left)
{
w=x->parent->right;
if(w->color==RED) //case 1
{
w->color=BLACK;
x->parent->color=RED;
leftRotate(x->parent);
w=x->parent->right;
}
if(w->left->color==BLACK &&
w->right->color==BLACK) //case 2
{
w->color=RED;
x=x->parent;
}
else
{
if(w->right->color==BLACK) //case 3
{
w->color=RED;
w->left->color=BLACK;
w=w->left;
rightRotate(w->parent);
}
w->right->color=BLACK; //case 4
w->color=w->parent->color;
x->parent->color=BLACK;
leftRotate(x->parent);
x=root;
}
}
else
{
w=x->parent->left;
if(w->color==RED)
{
w->color=BLACK;
x->parent->color=RED;
rightRotate(x->parent);
w=x->parent->left;
}
if(w->left->color==BLACK && w->right->color==BLACK)
{
w->color=RED;
x=x->parent;
}
else
{
if(w->left->color==BLACK)
{
w->color=RED;
w->right->color=BLACK;
w=w->right;
leftRotate(w->parent);
}
w->left->color=BLACK;
w->color=w->parent->color;
x->parent->color=BLACK;
rightRotate(x->parent);
x=root;
}
}
}
x->color=BLACK;
}
int main()
{
RBNode<int>* a1=new RBNode<int>(6);
RBNode<int>* a2=new RBNode<int>(5);
RBNode<int>* a3=new RBNode<int>(4);
RBNode<int>* a4=new RBNode<int>(3);
RBNode<int>* a5=new RBNode<int>(2);
RBNode<int>* a6=new RBNode<int>(1);
RBTree<int> *T=new RBTree<int> (a1);
T->inorder(T->root);
cout << endl;
T->Insert(a2);
T->Insert(a3);
T->Insert(a4);
T->Insert(a5);
T->Insert(a6);
RBNode<int> *p=T->search(4,T->root);
T->Delete(p);
T->inorder(T->root);
cout << endl;
T->Delete(a6);
T->Delete(a5);
T->Delete(a4);
T->Delete(a2);
T->inorder(T->root);
cout << endl;
T->Delete(a1);
T->inorder(T->root);
cout<<"The tree is empty now."<<endl;
}