#include
using namespace std;
enum{
RED,
BLACK,
DOUBLE_BLACK
};
struct Node{
int data, color;
Node *left, *right, *parent;
Node(int data){
this->data = data;
this->color = RED;
left = right = parent = NULL;
}
};
class RedBlackTree{
private:
Node *root;
void rotateLeft(Node *node){
Node *right = node->right;
node->right = right->left;
if(node->right != NULL)
node->right->parent = node;
right->parent = node->parent;
if(node->parent == NULL)
root = right;
else if(node == node->parent->left)
node->parent->left = right;
else
node->parent->right = right;
right->left = node;
node->parent = right;
}
void rotateRight(Node *node){
Node *left = node->left;
node->left = left->right;
if(node->left != NULL)
node->left->parent = node;
left->parent = node->parent;
if(node->parent == NULL)
root = left;
else if(node == node->parent->left)
node->parent->left = left;
else
node->parent->right = left;
left->right = node;
node->parent = left;
}
void fixInsertion(Node *node){
if(root == node){
node->color = BLACK;
return;
}
while(node->color != BLACK && node->parent->color == RED){
Node *grand_parent = node->parent->parent;
//When parent of new node is left child of grandparents of new node
if(grand_parent->left == node->parent){
Node *temp = grand_parent->right;
//If new node's grand parent right child is red, recolor
if(grand_parent->right != NULL && temp->color == RED){
node->parent->color = temp->color = BLACK;
grand_parent->color = RED;
node = grand_parent;
}else{
//If node is right child of its parent, left rotate
if(node->parent->right == node){
rotateLeft(node->parent);
node = node->parent;
}
//If node is left child of its parent, right rotate
rotateRight(grand_parent);
swap(node->parent->color, grand_parent->color);
node = node->parent;
}
//When parent of new node is right child of grandparents of new node
}else{
Node *temp = grand_parent->left;
//If grandparent left child is red, recolor
if(grand_parent->left != NULL && temp->color == RED){
node->parent->color = temp->color = BLACK;
grand_parent->color = RED;
node = grand_parent;
}else{
//If node is left child of its parent, right rotate (Same as right grandparent child case)
if(node->parent->left == node){
rotateRight(node);
node = node->parent;
}
//If node is right click of its parent, left rotate
rotateLeft(node);
swap(node->parent->color, grand_parent->color);
node = node->parent;
}
}
root->color = BLACK;
}
}
Node* getSmallestNode(Node *node){
Node *curr = node;
while(curr->left != NULL)
curr = curr->left;
return curr;
}
//Normal BST delete process
Node* deleteValue(Node *root, int target){
if(root == NULL)
return root;
if(target < root->data)
return deleteValue(root->left, target);
if(target > root->data)
return deleteValue(root->right, target);
if(root->left == NULL || root->right == NULL)
return root;
Node *temp = getSmallestNode(root->right);
root->data = temp->data;
return deleteValue(root->right, temp->data);
}
int getColor(Node *node){
if(node == NULL)
return BLACK;
return node->color;
}
void fixDeletion(Node *node){
if(node == NULL)
return;
if(node == root){
root = NULL;
return;
}
if(getColor(node) == RED || getColor(node->left) == RED || getColor(node->right) == RED){
Node *child = node->left != nullptr ? node->left : node->right;
if(node == node->parent->left){
node->parent->left = child;
if(child != NULL){
child->parent = node->parent;
child->color = BLACK;
}
delete(node);
}else{
node->parent->right = child;
if(child != NULL){
child->parent = node->parent;
child->color = BLACK;
}
delete(node);
}
}else{
Node *parent, *sibling, *temp;
parent = sibling = NULL;
temp = node;
temp->color = DOUBLE_BLACK;
while(temp != root && getColor(temp) == DOUBLE_BLACK){
parent = temp->parent;
if(temp == parent->left){
sibling = parent->right;
if(getColor(sibling) == RED){
sibling->color = BLACK;
parent->color = RED;
rotateLeft(parent);
}else{
if(getColor(sibling->left) == BLACK && getColor(sibling->right) == BLACK){
sibling->color = RED;
if(getColor(parent) == RED)
parent->color = BLACK;
else
parent->color = DOUBLE_BLACK;
temp = parent;
}else{
if(getColor(sibling->right) == BLACK){
sibling->left->color = BLACK;
sibling->color = RED;
rotateRight(sibling);
sibling = parent->right;
}
sibling->color = parent->color;
parent->color = sibling->right->color = BLACK;
rotateLeft(parent);
break;
}
}
}else{
sibling = parent->left;
if(getColor(sibling) == RED){
sibling->color = BLACK;
parent->color = RED;
rotateRight(parent);
}else{
if(getColor(sibling->left) == BLACK && getColor(sibling->right) == BLACK){
sibling->color = RED;
if(getColor(parent) == RED)
parent->color = BLACK;
else
parent->color = DOUBLE_BLACK;
temp = parent;
}else{
if(getColor(sibling->left) == BLACK){
sibling->right->color = BLACK;
sibling->color = RED;
rotateLeft(sibling);
sibling = parent->left;
}
sibling->color = parent->color;
parent->color = sibling->left->color = BLACK;
rotateRight(parent);
break;
}
}
}
}
if(node == node->parent->left)
node->parent->left = NULL;
else
node->parent->right = NULL;
delete(node);
root->color = BLACK;
}
}
public:
RedBlackTree(){
this->root = NULL;
}
void insertNode(int data){
Node *node = new Node(data);
if(root == NULL){
this->root = node;
}else{
Node *curr = root, *parent;
while(curr != NULL){
parent = curr;
if(curr->data < data)
curr = curr->right;
else
curr = curr->left;
}
node->parent = parent;
if(parent->data < data)
parent->right = node;
else
parent->left = node;
}
fixInsertion(node);
}
void deleteNode(int target){
Node *node = deleteValue(root, target);
fixDeletion(node);
}
void searchNode(int target){
Node *curr = root;
while(curr->data != target){
if(curr->data < target){
curr = curr->right;
}else{
curr = curr->left;
}
}
printf("Color of Node %d : %s\n", target, (curr->color == BLACK ? "BLACK" : "RED"));
}
};
int main(){
RedBlackTree tree;
tree.insertNode(7);
tree.insertNode(6);
tree.insertNode(5);
tree.insertNode(4);
tree.insertNode(3);
tree.insertNode(2);
tree.insertNode(1);
tree.deleteNode(4);
tree.deleteNode(3);
tree.searchNode(6);
return 0;
}