Last Updated : 23 Jul, 2025
A Red Black Tree is a self-balancing binary search tree where each node has an extra bit for denoting the color of the node, either red or black. This color coding is used to ensure that the tree remains balanced during insertions and deletions. In this article, we will learn how to implement a Red-Black Tree in C++ along with its basic operations.
What is a Red Black Tree?A Red Black Tree is a type of self-balancing binary search tree. It maintains a near-perfect balance by coloring each node-red or black and enforcing a set of properties that guarantee that the deepest path in the tree is no more than twice as long as the shallowest path.
Properties of Red-Black TreesA Red Black Tree can be implemented as an extension of a binary search tree. Each node in the tree will have an extra attribute to store its color.
Representation of Red Black Tree in C++To represent a Red Black Tree in C++, we'll use a struct Node to represent each node of the red-black tree and a class RedBlackTree that will contain all of the member functions. We have used the template to keep the red-black tree generic so that it can support multiple data types.
enum Color { RED, BLACK };template <typename T>
class RedBlackTree {
private:
struct Node {
T data;
Color color;
Node *left;
Node*right;
Node*parent;
};
Here,
The following diagram represents the structure of red black tree:
Red-Black-Tree Diagram Basic Operations of Red Black Tree in C++Following are some of the basic operations of a Red Black Tree that are required to manipulate its elements:
Operation
Description
Time Complexity
Space Complexity
Insert
Inserts a new element into the tree.
O(log n)
O(1)
Delete node
Removes an element from the tree.
O(log n)
O(1)
Search
Searches for an element in the tree.
O(log n)
O(1)
Left Rotate
Performs a left rotation on a given node.
O(1)
O(1)
Right Rotate
Performs a right rotation on a given node.
O(1)
O(1)
Here, n represents the number of nodes in the red black tree.
Implementation of Insert FunctionImplementation of Delete Node Function
- Perform standard BST insertion and color the newly inserted node red.
- If the newly inserted node is the root, color it black and return.
- Do the following while the parent of the newly inserted node is red:
- If the parent is the left child of the grandparent:
- If the right child of the grandparent is red, recolor and move up the tree.
- Else, perform rotations and recolor.
- If the parent is the right child of the grandparent:
- If the left child of the grandparent is red, recolor and move up the tree.
- Else, perform rotations and recolor.
- Color the root black.
Implementation of Search Function
- Perform standard BST deletion.
- If the deleted node was red, we're done.
- If the deleted node was black, we need to fix the double black violation:
- If the sibling is red, perform rotations and recolor.
- If the sibling is black with both black children, recolor and move up the tree.
- If the sibling is black with at least one red child, perform rotations and recolor.
Implementation of Rotation Functions
- Start from the root node.
- Compare the value to be searched with the value of the current node.
- If the value is less than the current node, move to the left child.
- If the value is greater than the current node, move to the right child.
- If the value is equal to the current node, return true.
- If a leaf node is reached and the value is not found, return false.
C++ Program to Implement Red Black Tree
- Left Rotation:
- Make the right child of the current node the new root of the subtree.
- Make the old root the left child of the new root.
- Update the parent pointers accordingly.
- Right Rotation:
- Make the left child of the current node the new root of the subtree.
- Make the old root the right child of the new root.
- Update the parent pointers accordingly.
The following program demonstrates the implementation of a Red Black Tree in C++:
C++
// C++ Program to Implement Red Black Tree
#include <iostream>
using namespace std;
// Enumeration for colors of nodes in Red-Black Tree
enum Color { RED, BLACK };
// Class template for Red-Black Tree
template <typename T> class RedBlackTree {
private:
// Structure for a node in Red-Black Tree
struct Node {
T data;
Color color;
Node* parent;
Node* left;
Node* right;
// Constructor to initialize node with data and
// color
Node(T value)
: data(value)
, color(RED)
, parent(nullptr)
, left(nullptr)
, right(nullptr)
{
}
};
Node* root; // Root of the Red-Black Tree
// Utility function: Left Rotation
void rotateLeft(Node*& node)
{
Node* child = node->right;
node->right = child->left;
if (node->right != nullptr)
node->right->parent = node;
child->parent = node->parent;
if (node->parent == nullptr)
root = child;
else if (node == node->parent->left)
node->parent->left = child;
else
node->parent->right = child;
child->left = node;
node->parent = child;
}
// Utility function: Right Rotation
void rotateRight(Node*& node)
{
Node* child = node->left;
node->left = child->right;
if (node->left != nullptr)
node->left->parent = node;
child->parent = node->parent;
if (node->parent == nullptr)
root = child;
else if (node == node->parent->left)
node->parent->left = child;
else
node->parent->right = child;
child->right = node;
node->parent = child;
}
// Utility function: Fixing Insertion Violation
void fixInsert(Node*& node)
{
Node* parent = nullptr;
Node* grandparent = nullptr;
while (node != root && node->color == RED
&& node->parent->color == RED) {
parent = node->parent;
grandparent = parent->parent;
if (parent == grandparent->left) {
Node* uncle = grandparent->right;
if (uncle != nullptr
&& uncle->color == RED) {
grandparent->color = RED;
parent->color = BLACK;
uncle->color = BLACK;
node = grandparent;
}
else {
if (node == parent->right) {
rotateLeft(parent);
node = parent;
parent = node->parent;
}
rotateRight(grandparent);
swap(parent->color, grandparent->color);
node = parent;
}
}
else {
Node* uncle = grandparent->left;
if (uncle != nullptr
&& uncle->color == RED) {
grandparent->color = RED;
parent->color = BLACK;
uncle->color = BLACK;
node = grandparent;
}
else {
if (node == parent->left) {
rotateRight(parent);
node = parent;
parent = node->parent;
}
rotateLeft(grandparent);
swap(parent->color, grandparent->color);
node = parent;
}
}
}
root->color = BLACK;
}
// Utility function: Fixing Deletion Violation
void fixDelete(Node*& node)
{
while (node != root && node->color == BLACK) {
if (node == node->parent->left) {
Node* sibling = node->parent->right;
if (sibling->color == RED) {
sibling->color = BLACK;
node->parent->color = RED;
rotateLeft(node->parent);
sibling = node->parent->right;
}
if ((sibling->left == nullptr
|| sibling->left->color == BLACK)
&& (sibling->right == nullptr
|| sibling->right->color
== BLACK)) {
sibling->color = RED;
node = node->parent;
}
else {
if (sibling->right == nullptr
|| sibling->right->color == BLACK) {
if (sibling->left != nullptr)
sibling->left->color = BLACK;
sibling->color = RED;
rotateRight(sibling);
sibling = node->parent->right;
}
sibling->color = node->parent->color;
node->parent->color = BLACK;
if (sibling->right != nullptr)
sibling->right->color = BLACK;
rotateLeft(node->parent);
node = root;
}
}
else {
Node* sibling = node->parent->left;
if (sibling->color == RED) {
sibling->color = BLACK;
node->parent->color = RED;
rotateRight(node->parent);
sibling = node->parent->left;
}
if ((sibling->left == nullptr
|| sibling->left->color == BLACK)
&& (sibling->right == nullptr
|| sibling->right->color
== BLACK)) {
sibling->color = RED;
node = node->parent;
}
else {
if (sibling->left == nullptr
|| sibling->left->color == BLACK) {
if (sibling->right != nullptr)
sibling->right->color = BLACK;
sibling->color = RED;
rotateLeft(sibling);
sibling = node->parent->left;
}
sibling->color = node->parent->color;
node->parent->color = BLACK;
if (sibling->left != nullptr)
sibling->left->color = BLACK;
rotateRight(node->parent);
node = root;
}
}
}
node->color = BLACK;
}
// Utility function: Find Node with Minimum Value
Node* minValueNode(Node*& node)
{
Node* current = node;
while (current->left != nullptr)
current = current->left;
return current;
}
// Utility function: Transplant nodes in Red-Black Tree
void transplant(Node*& root, Node*& u, Node*& v)
{
if (u->parent == nullptr)
root = v;
else if (u == u->parent->left)
u->parent->left = v;
else
u->parent->right = v;
if (v != nullptr)
v->parent = u->parent;
}
// Utility function: Helper to print Red-Black Tree
void printHelper(Node* root, string indent, bool last)
{
if (root != nullptr) {
cout << indent;
if (last) {
cout << "R----";
indent += " ";
}
else {
cout << "L----";
indent += "| ";
}
string sColor
= (root->color == RED) ? "RED" : "BLACK";
cout << root->data << "(" << sColor << ")"
<< endl;
printHelper(root->left, indent, false);
printHelper(root->right, indent, true);
}
}
// Utility function: Delete all nodes in the Red-Black
// Tree
void deleteTree(Node* node)
{
if (node != nullptr) {
deleteTree(node->left);
deleteTree(node->right);
delete node;
}
}
public:
// Constructor: Initialize Red-Black Tree
RedBlackTree()
: root(nullptr)
{
}
// Destructor: Delete Red-Black Tree
~RedBlackTree() { deleteTree(root); }
// Public function: Insert a value into Red-Black Tree
void insert(T key)
{
Node* node = new Node(key);
Node* parent = nullptr;
Node* current = root;
while (current != nullptr) {
parent = current;
if (node->data < current->data)
current = current->left;
else
current = current->right;
}
node->parent = parent;
if (parent == nullptr)
root = node;
else if (node->data < parent->data)
parent->left = node;
else
parent->right = node;
fixInsert(node);
}
// Public function: Remove a value from Red-Black Tree
void remove(T key)
{
Node* node = root;
Node* z = nullptr;
Node* x = nullptr;
Node* y = nullptr;
while (node != nullptr) {
if (node->data == key) {
z = node;
}
if (node->data <= key) {
node = node->right;
}
else {
node = node->left;
}
}
if (z == nullptr) {
cout << "Key not found in the tree" << endl;
return;
}
y = z;
Color yOriginalColor = y->color;
if (z->left == nullptr) {
x = z->right;
transplant(root, z, z->right);
}
else if (z->right == nullptr) {
x = z->left;
transplant(root, z, z->left);
}
else {
y = minValueNode(z->right);
yOriginalColor = y->color;
x = y->right;
if (y->parent == z) {
if (x != nullptr)
x->parent = y;
}
else {
transplant(root, y, y->right);
y->right = z->right;
y->right->parent = y;
}
transplant(root, z, y);
y->left = z->left;
y->left->parent = y;
y->color = z->color;
}
delete z;
if (yOriginalColor == BLACK) {
fixDelete(x);
}
}
// Public function: Print the Red-Black Tree
void printTree()
{
if (root == nullptr)
cout << "Tree is empty." << endl;
else {
cout << "Red-Black Tree:" << endl;
printHelper(root, "", true);
}
}
};
// Driver program to test Red-Black Tree
int main()
{
RedBlackTree<int> rbtree;
// Inserting values into Red-Black Tree
rbtree.insert(7);
rbtree.insert(3);
rbtree.insert(18);
rbtree.insert(10);
rbtree.insert(22);
rbtree.insert(8);
rbtree.insert(11);
rbtree.insert(26);
rbtree.insert(2);
rbtree.insert(6);
// Printing Red-Black Tree
rbtree.printTree();
// Deleting nodes from Red-Black Tree
cout << "After deleting 18:" << endl;
rbtree.remove(18);
rbtree.printTree();
cout << "After deleting 11:" << endl;
rbtree.remove(11);
rbtree.printTree();
cout << "After deleting 3:" << endl;
rbtree.remove(3);
rbtree.printTree();
return 0;
}
Output
Red-Black Tree:Applications of Red Black Tree
R----7(BLACK)
L----3(BLACK)
| L----2(RED)
| R----6(RED)
R----18(RED)
L----10(BLACK)
| L----8(RED)
| R----11(RED)
R----22(BLACK)
R----26(RED)After deleting 18:
Red-Black Tree:
R----7(BLACK)
L----3(BLACK)
| L----2(RED)
| R----6(RED)
R----22(RED)
L----10(BLACK)
| L----8(RED)
| R----11(RED)
R----26(BLACK)After deleting 11:
Red-Black Tree:
R----7(BLACK)
L----3(BLACK)
| L----2(RED)
| R----6(RED)
R----22(RED)
L----10(BLACK)
| L----8(RED)
R----26(BLACK)After deleting 3:
Red-Black Tree:
R----7(BLACK)
L----6(BLACK)
| L----2(RED)
R----22(RED)
L----10(BLACK)
| L----8(RED)
R----26(BLACK)
Following are some of the common applications of red black tree:
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4