Red black tree is a binary search tree in which every node is colored either red or black. Each node in a Red-Black Tree has an extra bit for denoting the color of the node, either red or black.
Insertion in a Red-Black Tree starts like a regular binary search tree insertion and then makes adjustments to maintain the Red-Black properties.
RB-INSERT(T, k)
BST-INSERT(T, k) //normal BST insertion
while k.parent.color == RED
if k.parent == k.parent.parent.right
u = k.parent.parent.left //uncle
if u.color == RED
u.color = BLACK
k.parent.color = BLACK
k.parent.parent.color = RED
k = k.parent.parent
else if k == k.parent.left
k = k.parent
LEFT-ROTATE(T, k)
k.parent.color = BLACK
k.parent.parent.color = RED
RIGHT-ROTATE(T, k.parent.parent)
else (same as then clause with “left” and “right” exchanged)
T.root.color = BLACK
Deletion operations in a Red-Black Tree (RBT) can be quite complex due to the balancing rules that need to be maintained. In delete operation, we check color of sibling to decide the appropriate case. In delete, the main violated property is, in each path the same number of black nodes.
1. Find the Node: Like in a regular binary search tree, find the node that needs to be deleted.
2. Perform Standard BST Delete:
RB-DELETE(T, x)
BST-DELETE(T, x)
while x ≠ T.root and x.color == BLACK
if x == x.parent.left
s = x.parent.right
if s.color == RED
s.color = BLACK
x.parent.color = RED
LEFT-ROTATE(T, x.parent)
s = x.parent.right
if s.left.color == BLACK and s.right.color == BLACK
s.color = RED
x = x.parent
else if s.right.color == BLACK
s.left.color = BLACK
s.color = RED
RIGHT-ROTATE(T, s)
s = x.parent.right
s.color = x.parent.right
x.parent.color = BLACK
s.right.color = BLACK
LEFT-ROTATE(T, x.parent)
x = T.root
else (same as then close with “right” and “left” exchanged)
x.color = BLACK
// Red Black Tree operations in C
#include <stdio.h>
#include <stdlib.h>
// Red-Black Tree Node Structure
typedef struct Node {
int data;
struct Node* parent;
struct Node* left;
struct Node* right;
int color; // 0 for black, 1 for red
} Node;
// Red-Black Tree Structure
typedef struct RedBlackTree {
Node* root;
} RedBlackTree;
// Create a new Red-Black Tree Node
Node* createNode(int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (newNode == NULL) {
printf("Memory allocation error\n");
exit(1);
}
newNode->data = data;
newNode->parent = newNode->left = newNode->right = NULL;
newNode->color = 1; // New nodes are initially red
return newNode;
}
// Create a new Red-Black Tree
RedBlackTree* createRedBlackTree() {
RedBlackTree* newTree = (RedBlackTree*)malloc(sizeof(RedBlackTree));
if (newTree == NULL) {
printf("Memory allocation error\n");
exit(1);
}
newTree->root = NULL;
return newTree;
}
// Function to perform left rotation
void leftRotate(RedBlackTree* tree, Node* x) {
Node* y = x->right;
x->right = y->left;
if (y->left != NULL)
y->left->parent = x;
y->parent = x->parent;
if (x->parent == NULL)
tree->root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y;
}
// Function to perform right rotation
void rightRotate(RedBlackTree* tree, Node* y) {
Node* x = y->left;
y->left = x->right;
if (x->right != NULL)
x->right->parent = y;
x->parent = y->parent;
if (y->parent == NULL)
tree->root = x;
else if (y == y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
x->right = y;
y->parent = x;
}
// Function to fix the Red-Black Tree properties after insertion
void insertFixup(RedBlackTree* tree, Node* z) {
while (z->parent != NULL && z->parent->color == 1) {
if (z->parent == z->parent->parent->left) {
Node* y = z->parent->parent->right;
if (y != NULL && y->color == 1) {
z->parent->color = 0; // Black
y->color = 0; // Black
z->parent->parent->color = 1; // Red
z = z->parent->parent;
} else {
if (z == z->parent->right) {
z = z->parent;
leftRotate(tree, z);
}
z->parent->color = 0; // Black
z->parent->parent->color = 1; // Red
rightRotate(tree, z->parent->parent);
}
} else {
Node* y = z->parent->parent->left;
if (y != NULL && y->color == 1) {
z->parent->color = 0; // Black
y->color = 0; // Black
z->parent->parent->color = 1; // Red
z = z->parent->parent;
} else {
if (z == z->parent->left) {
z = z->parent;
rightRotate(tree, z);
}
z->parent->color = 0; // Black
z->parent->parent->color = 1; // Red
leftRotate(tree, z->parent->parent);
}
}
}
tree->root->color = 0; // Root must be black
}
// Function to insert a node into the Red-Black Tree
void insert(RedBlackTree* tree, int data) {
Node* z = createNode(data);
Node* y = NULL;
Node* x = tree->root;
while (x != NULL) {
y = x;
if (z->data < x->data)
x = x->left;
else
x = x->right;
}
z->parent = y;
if (y == NULL)
tree->root = z;
else if (z->data < y->data)
y->left = z;
else
y->right = z;
insertFixup(tree, z);
}
// Function to find the minimum value node in the tree rooted at a given node
Node* findMinValueNode(Node* node) {
Node* current = node;
while (current->left != NULL)
current = current->left;
return current;
}
// Function to fix the Red-Black Tree properties after deletion
void deleteFixup(RedBlackTree* tree, Node* x) {
while (x != tree->root && x->color == 0) {
if (x == x->parent->left) {
Node* w = x->parent->right;
if (w->color == 1) {
w->color = 0; // Black
x->parent->color = 1; // Red
leftRotate(tree, x->parent);
w = x->parent->right;
}
if (w->left->color == 0 && w->right->color == 0) {
w->color = 1; // Red
x = x->parent;
} else {
if (w->right->color == 0) {
w->left->color = 0; // Black
w->color = 1; // Red
rightRotate(tree, w);
w = x->parent->right;
}
w->color = x->parent->color;
x->parent->color = 0; // Black
w->right->color = 0; // Black
leftRotate(tree, x->parent);
x = tree->root;
}
} else {
Node* w = x->parent->left;
if (w->color == 1) {
w->color = 0; // Black
x->parent->color = 1; // Red
rightRotate(tree, x->parent);
w = x->parent->left;
}
if (w->right->color == 0 && w->left->color == 0) {
w->color = 1; // Red
x = x->parent;
} else {
if (w->left->color == 0) {
w->right->color = 0; // Black
w->color = 1; // Red
leftRotate(tree, w);
w = x->parent->left;
}
w->color = x->parent->color;
x->parent->color = 0; // Black
w->left->color = 0; // Black
rightRotate(tree, x->parent);
x = tree->root;
}
}
}
x->color = 0; // Black
}
// Function to delete a node from the Red-Black Tree
void delete(RedBlackTree* tree, int data) {
Node* z = tree->root;
while (z != NULL) {
if (data == z->data) {
Node* y = z;
Node* x;
int yOriginalColor = y->color;
if (z->left == NULL) {
x = z->right;
transplant(tree, z, z->right);
} else if (z->right == NULL) {
x = z->left;
transplant(tree, z, z->left);
} else {
y = findMinValueNode(z->right);
yOriginalColor = y->color;
x = y->right;
if (y->parent == z) {
if (x != NULL)
x->parent = y;
} else {
transplant(tree, y, y->right);
y->right = z->right;
if (y->right != NULL)
y->right->parent = y;
}
transplant(tree, z, y);
y->left = z->left;
y->left->parent = y;
y->color = z->color;
}
free(z);
if (yOriginalColor == 0)
deleteFixup(tree, x);
return;
} else if (data < z->data)
z = z->left;
else
z = z->right;
}
}
// Transplant the subtree rooted at node u with the subtree rooted at node v
void transplant(RedBlackTree* tree, Node* u, Node* v) {
if (u->parent == NULL)
tree->root = v;
else if (u == u->parent->left)
u->parent->left = v;
else
u->parent->right = v;
if (v != NULL)
v->parent = u->parent;
}
// Function to perform in-order traversal of the Red-Black Tree
void inOrderTraversal(Node* root) {
if (root != NULL) {
inOrderTraversal(root->left);
printf("%d ", root->data);
inOrderTraversal(root->right);
}
}
// Function to free memory by deallocating nodes
void freeMemory(Node* root) {
if (root == NULL)
return;
freeMemory(root->left);
freeMemory(root->right);
free(root);
}
int main() {
int choice,value;
RedBlackTree* tree = createRedBlackTree();
do
{
printf("1. Insertion\n2. Deletion\n3. Display\n4. Exit");
printf("\nEnter your choice: ");
scanf("%d",&choice);
switch(choice)
{
case 1: printf("Enter the value to be insert: ");
scanf("%d",&value);
insert(tree, value);
break;
case 2: printf("Enter the value to be deleted: ");
scanf("%d",&value);
delete(tree, value);
break;
case 3: inOrderTraversal(tree->root);
break;
case 4: freeMemory(tree->root);
break;
default: printf("\nWrong selection!!! Try again!!!");
}
}while(choice!=4);
return(0);
}