//
// main.cpp
// RBTree
//
// Created by 孟文斌 on 15/4/22.
// Copyright (c) 2015年 孟文斌. All rights reserved.
//
#include <iostream>
#include <stack>
#include <queue>
#include <time.h>
using namespace std;
const int COLOR_RED = 0;
const int COLOR_BLACK = 1;
struct TreeNode{
int key;
int color;//0red 1black
TreeNode* p;
TreeNode *left;
TreeNode *right;
TreeNode(int x,int c,TreeNode *init):key(x),color(c),p(init),left(init),right(init){}
TreeNode(int x,int c):key(x),color(c),p(NULL),left(NULL),right(NULL){}
};
TreeNode * const nill = new TreeNode(-1,COLOR_BLACK);
class RBTree{
private:
TreeNode * root;
//when val is not the minmun of the Tree find the Node which key is min less than the val
//when val is the minmun of the Tree find the Node which key is min larger than the val
TreeNode* findPos(int val){
TreeNode* t = root;
TreeNode *pre = root;
while(t != nill){
if(t->key == val) return t;
pre = t;
if(t->key < val) t = t->right;
else t = t->left;
}
return pre;
}
void RB_left_rotate(TreeNode* t){//t call left rotation operation
if(t == NULL || t == nill) return;
TreeNode* p = t->p,*s = t->right;
if(s == nill) return;
t->right = s->left;
if(s->left != nill) s->left->p = t;
s->left = t;
t->p = s;
if(p != nill){
if(p->left == t) p->left = s;
else p->right = s;
}else{
root = s;
}
s->p = p;
}
void RB_right_rotate(TreeNode* t){//t call right rotation operation
if(t == NULL || t == nill) return;
TreeNode* p = t->p,*s = t->left;
if(s == nill) return;
t->left = s->right;
if(s->right != nill) s->right->p = t;
s->right = t;
t->p = s;
if(p != nill){
if(p->left == t) p->left = s;
else p->right = s;
}else{
root = s;
}
s->p = p;
}
void RB_insert_fixup(TreeNode* t){
if(t == nill || t->p == root) return;
while(t->p->color == COLOR_RED){
if(t->p == t->p->p->left){//t's father is in left tree
// t's father and uncle are both red: change father and uncle into black and t's grandfather into red
if(t->p->p->right->color == COLOR_RED){
t->p->color = COLOR_BLACK;
t->p->p->right->color = COLOR_BLACK;
t->p->p->color = COLOR_RED;
t = t->p->p;
}else{
if(t == t->p->right) {//uncle is black and t is the right child
t = t->p;
RB_left_rotate(t);
}
t->p->color = COLOR_BLACK;//uncle is black and t is the left child
t->p->p->color = COLOR_RED;
RB_right_rotate(t->p->p);
}
}else {//exchange the direction
if(t->p->p->left->color == COLOR_RED){
t->p->color = COLOR_BLACK;
t->p->p->left->color = COLOR_BLACK;
t->p->p->color = COLOR_RED;
t = t->p->p;
}else{
if(t == t->p->left) {
t = t->p;
RB_right_rotate(t);
}
t->p->color = COLOR_BLACK;
t->p->p->color = COLOR_RED;
RB_left_rotate(t->p->p);
}
}
}
root->color = COLOR_BLACK;
}
void RB_delete_fixup(TreeNode* t){
if(t == NULL) return;
TreeNode* w = NULL;
while(t != root && t->color == COLOR_BLACK){
if(t == t->p->left){//t is left child
w = t->p->right;
if(w->color == COLOR_RED){//brother is red
w->color = COLOR_BLACK;
t->p->color = COLOR_RED;
RB_left_rotate(t->p);
w = t->p->right;
}
if(w->left->color==COLOR_BLACK && w->right->color==COLOR_BLACK){
//brother is black and his children are also black
w->color = COLOR_RED;
t = t->p;
}else {
if(w->right->color == COLOR_BLACK){//left child is black and right child is red
w->left->color = COLOR_BLACK;
w->color = COLOR_RED;
RB_right_rotate(w);
w = t->p->right;
}
w->color = t->p->color;//right child is red
t->p->color = COLOR_BLACK;
w->right->color = COLOR_BLACK;
RB_left_rotate(t->p);
t = root;
}
}else{//exchanged all direction
w = t->p->left;
if(w->color == COLOR_RED){//brother is red
w->color = COLOR_BLACK;
t->p->color = COLOR_RED;
RB_right_rotate(t->p);
w = t->p->left;
}
if(w->left->color==COLOR_BLACK && w->right->color==COLOR_BLACK){//brother is black and his children are also black
w->color = COLOR_RED;
t = t->p;
}else {
if(w->left->color == COLOR_BLACK){//left child is black and right child is red
w->right->color = COLOR_BLACK;
cout<<endl;
w->color = COLOR_RED;
RB_left_rotate(w);
cout<<endl;
w = t->p->left;
}
w->color = t->p->color;//right child is red
w->left->color = COLOR_BLACK;
t->p->color = COLOR_BLACK;
RB_right_rotate(t->p);
t = root;
}
}
}
t->color = COLOR_BLACK;
}
/**
* insert a Node into the Tree
*/
void insertTreeNode(TreeNode* t){
TreeNode * pre = findPos(t->key);//find the pos to insert
if(pre->key == t->key) return;
if(pre->key < t->key) pre->right = t;
else pre->left = t;
t->p = pre;
RB_insert_fixup(t);// fix the tree
}
/**
* delete a Node from the Tree
*/
void deleteTreeNode(TreeNode* z){
if(z == NULL || z==nill) {
return;
}
TreeNode *y = NULL,*x = NULL;
if(z->left==nill || z->right==nill) y = z;//t is single
else y = Tree_Successor(z);// t has both right and left child
if(y->left != nill) x = y->left;//t's left child is not nill point x to s's left
else x = y->right;
x->p = y->p; //point x's parent to s's parent
if(y->p == nill) root = x;
else if(y->p->left == y) y->p->left = x;
else y->p->right = x;
if(y != z) z->key = y->key; // chage the z to y and y is deleted
if(y->color == COLOR_BLACK) RB_delete_fixup(x);//fix the tree
}
TreeNode * Tree_Minimum(TreeNode *x){
TreeNode *r = x;
while(r->left != nill)
r = r->left;
return r;
}
TreeNode * Tree_Maximum(TreeNode *x){
TreeNode *r = x;
while(r->right != nill)
r = r->right;
return r;
}
TreeNode * Tree_Successor(TreeNode *x){
if(x->right != nill)
return Tree_Minimum(x->right);
TreeNode *y = x->p;
while(y != nill && x == y->right){
x = y;
y = y->p;
}
return y;
}
TreeNode * Tree_Predecesor(TreeNode *x){
if(x->left != nill)
return Tree_Maximum(x->left);
TreeNode *y = x->p;
while(y != nill && x == y->left){
x = y;
y = y->p;
}
return y;
}
public:
RBTree(int val){
root = new TreeNode(val,COLOR_BLACK,nill);
}
RBTree(){
root = nill;
}
void insertVals(int *val,int n){
for(int i=0;i<n;i++){
insertVal(val[i]);
}
}
void clearTree(){
root = NULL;
nill->p = NULL;
//delete other elements garbage collect
}
void reBuildTree(int *val,int n){
clearTree();
for(int i=0;i<n;i++){
insertVal(val[i]);
}
}
/**
* insert val into tree
*/
void insertVal(int val){
if(root == NULL || root == nill) {
root = new TreeNode(val,COLOR_BLACK,nill);
return;
}
TreeNode *t = new TreeNode(val,COLOR_RED,nill);
insertTreeNode(t);
}
void deleteVal(int val){
TreeNode *z = findPos(val);
if(z->key != val) return;// can't find the val
deleteTreeNode(z);
}
bool valExit(int val){
TreeNode * pre = findPos(val);
if(pre->key == val) return 1;
return 0;
}
void inOrderDisplay(){
if(!root) return;
stack<TreeNode*> s;
TreeNode* tmp = root;
int num=0;
while(tmp!=nill){
s.push(tmp);
tmp = tmp->left;
}
while(!s.empty()){
tmp = s.top();
s.pop();
num++;
cout<<tmp->key<<" "<<tmp->color<<" ;";
tmp = tmp->right;
while(tmp != nill){
s.push(tmp);
tmp = tmp->left;
}
}
cout<<"num:"<<num<<endl;
}
void layerOrderDisplay(){
if(!root) return;
queue<TreeNode*> q1,q2;
TreeNode* tmp = root;
q1.push(tmp);
int layer = 0,num=0;
while(!q1.empty()){
layer ++;
while(!q1.empty()){
tmp = q1.front();
q1.pop();
num++;
cout<<tmp->key<<"->"<<tmp->color<<"->"<<tmp->p->key<<endl;
if(tmp->left != nill ) q2.push(tmp->left);
if(tmp->right != nill ) q2.push(tmp->right);
}
swap(q1, q2);
}
cout<<"layer"<<layer<<" num:"<<num<<endl;
}
void deleteTest(){
deleteTreeNode(root->left);
}
~RBTree(){
delete root;
}
};
int main(int argc, const char * argv[]) {
RBTree a;
srand(time(0));
for(int k = 1;k<100000;k++){
srand(k);
int n = 100;
int *test = new int[n];
for(int i=0;i<n;i++){
test[i] = n*i;//rand();
}
a.insertVals(test, n);
for(int i=0;i<n/5;i++){
a.deleteVal(test[rand()%n]);
}
for(int i=0;i<n;i++){
test[i] = rand();
}
a.insertVals(test, n);
}
return 0;
}