#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int Elemtype;
#define RED 0
#define BLACK 1
struct RB_Tree{
Elemtype val;
int color;
struct RB_Tree *lchild, *rchild;
struct RB_Tree *parent;
};
typedef struct RB_Tree Node;
typedef struct RB_Tree* pNode;
pNode root;
pNode NIL ;
void rightRotate(pNode cur){
pNode aim = cur->lchild;
pNode parent = cur->parent;
if (parent != NIL) {
if(parent->lchild == cur)
parent->lchild = aim;
else
parent->rchild = aim;
}
pNode temp = aim->rchild;
aim->parent = parent;
cur->parent = aim;
temp->parent = cur;
cur->lchild = temp;
aim->rchild = cur;
if (parent == NIL) {
root = aim;
}
}
void leftRotate(pNode cur){
pNode aim = cur->rchild;
pNode parent = cur->parent;
if (parent != NIL) {
if (parent->lchild == cur) {
parent->lchild = aim;
}else
parent->rchild = aim;
}
pNode temp = aim->lchild;
cur->parent = aim;
temp->parent = cur;
aim->parent = parent;
aim->lchild = cur;
cur->rchild = temp;
if (parent == NIL) {
root = aim;
}
}
pNode successor(pNode cur){
printf("find successor of %d\n", cur->val);
pNode x = cur->rchild;
while (x->lchild != NIL) {
x = x->lchild;
}
return x;
pNode y = cur->parent;
x = cur;
while (y != NIL && x == y->rchild) {
x = y;
y = y ->parent;
}
return y;
}
void insertFixUp(pNode cur){
while(cur->parent->color == RED) {
if (cur->parent == cur->parent->parent->lchild) {
pNode y = cur->parent->parent->rchild;
if (y->color == RED) {
y->color = BLACK;
cur->parent->parent->color = RED;
cur->parent->color = BLACK;
cur = cur->parent->parent;
}else{
if( cur == cur->parent->rchild){
cur = cur->parent;
leftRotate(cur);
}
cur->parent->color = BLACK;
cur->parent->parent->color = RED;
rightRotate(cur->parent->parent);
}
}else if( cur->parent == cur->parent->parent->rchild){
pNode y = cur->parent->parent->lchild;
if (y->color == RED) {
y->color = BLACK;
cur->parent->parent->color = RED;
cur->parent->color = BLACK;
cur = cur->parent->parent;
}else{
if(cur == cur->parent->lchild){
cur = cur->parent;
rightRotate(cur);
}
cur->parent->color = BLACK;
cur->parent->parent->color = RED;
leftRotate(cur->parent->parent);
}
}
}
root->color = BLACK;
}
void insertNode(pNode &parent, Elemtype data){
if (parent == NULL) {
pNode tmp = (pNode) malloc(sizeof(Node));
tmp->lchild = tmp->rchild = NIL;
tmp->color = BLACK;
tmp->val = data;
tmp->parent = NIL;
root = tmp;
insertFixUp(tmp);
}
if (parent->val > data) {
if (parent->lchild == NIL) {
pNode tmp = (pNode )malloc(sizeof(Node));
tmp->lchild = tmp->rchild = NIL;
tmp->color = RED;
tmp->val = data;
tmp->parent = parent;
parent->lchild = tmp;
insertFixUp(tmp);
}else {
insertNode(parent->lchild, data);
}
}else if( parent->val < data){
if(parent->rchild == NIL){
pNode tmp = (pNode) malloc(sizeof(Node));
tmp->parent = parent;
tmp->lchild = tmp->rchild = NIL;
tmp->color = RED;
tmp->val = data;
parent->rchild = tmp;
insertFixUp(tmp);
}else {
insertNode(parent->rchild, data);
}
}
}
void findData(pNode cur,pNode &e, Elemtype data){
if (cur->val > data) {
findData(cur->lchild,e, data);
}else if(cur->val < data){
findData(cur->rchild,e, data);
}else if(cur->val == data ){
printf("-----cur->val: %d\n", cur->val);
e = cur;
}
}
void deleteFixUp(pNode &cur){
pNode x, y, w;
x = y = w = NULL;
while (cur != root && cur->color == BLACK) {
if (cur == cur->parent->lchild) {
w = cur->parent->rchild;
if(w->color == RED) {
w->color = BLACK;
w->parent->color = RED;
leftRotate(cur->parent);
w = cur->parent->rchild;
}if(w->lchild->color == BLACK && w->rchild->color == BLACK) {
w->color = RED;
cur = cur->parent;
}else if(w->rchild->color == RED){
w->lchild->color = BLACK;
w->color = RED;
rightRotate(w);
w = cur->parent->rchild;
}
w->color = w->parent->color;
w->parent->color = BLACK;
w->rchild->color = BLACK;
leftRotate(cur->parent);
cur = root;
}else {
w = cur->parent->lchild;
if (w->color == RED) {
w->color = BLACK;
w->parent->color = RED;
rightRotate(cur->parent);
w = cur->parent->rchild;
}if(w->lchild->color == BLACK && w->rchild->color == BLACK){
w->color = RED;
cur = cur->parent;
}else if(w->lchild->color == RED){
w->rchild ->color = BLACK;
w->color = RED;
leftRotate(w);
w = cur->parent->lchild;
}
w->color = w->parent->color;
w->parent->color = BLACK;
w->lchild->color = BLACK;
rightRotate(cur->parent);
cur = root;
}
}
cur->color = BLACK;
}
void deleteNode(pNode cur){
pNode y = NULL, x = NULL;
if(cur->lchild == NIL || cur->rchild == NIL)
y = cur;
else y = successor(cur);
printf("successor :%d\n", y->val);
if (y->lchild != NIL)
x = y->lchild;
else x = y->rchild;
x->parent = y->parent;
if (y->parent == NIL) {
root = x;
}else if( y == y->parent->lchild){
y->parent->lchild = x;
}else
y->parent->rchild = x;
if (y != cur) {
cur->val = y->val;
}
if (y->color == BLACK) {
deleteFixUp(x);
}
free(y);
}
void readTree(pNode rt){
if(rt == NIL){ return; }
printf("%d -- %s ----p: %d\n", rt->val, (rt->color == RED? "RED" : "BLACK"),(rt->parent != NIL? rt->parent->val: -1));
readTree(rt->lchild);
readTree(rt->rchild);
}
int main(){
NIL = (pNode) malloc(sizeof(Node));
NIL->color = BLACK;
NIL->val = -1;
int num[10] = {4, 3, 2, 1, 5, 6 ,7 , 8};
root = NULL;
int i = 0 ;
for(i = 0; i < 8; i++){
insertNode(root, num[i]);
printf("----------\n");
readTree(root);
puts("");
}
for( i = 0; i < 1; i++){
pNode cur = NIL;
findData(root,cur,2 );
if(cur != NIL){
printf("Delete : %d -- \n", num[i]);
deleteNode(cur);
readTree(root);
}
}
}