Algorithm


Insertion in a Red-Black Tree involves adding a new node to the tree while maintaining the properties of a Red-Black Tree. Red-Black Trees are a type of self-balancing binary search tree with additional properties that ensure logarithmic height and efficient operations.

The following are the steps to perform an insertion in a Red-Black Tree:

  1. Standard Binary Search Tree Insertion:

    • Start by inserting the new node into the Red-Black Tree using standard binary search tree insertion rules. This means finding the appropriate position for the new node based on its key and inserting it as a red node.
  2. Color the New Node Red:

    • After insertion, color the newly inserted node as red. This step doesn't violate any Red-Black Tree properties.
  3. Fix Violations:

    • Check and fix any Red-Black Tree properties that might have been violated during the insertion. There are three cases to consider:

    a. Case 1: The parent of the newly inserted node is black.

    • In this case, no properties are violated, and the tree remains a valid Red-Black Tree.

    b. Case 2: The parent of the newly inserted node is red.

    • If the parent is red, there is a violation of the property that prohibits consecutive red nodes. To fix this, apply rotations and recoloring as needed.

    c. Case 3: The uncle of the newly inserted node is red.

    • If both the parent and uncle are red, recolor the parent and uncle to black and the grandparent to red. Then, check if the grandparent violates any properties and recursively fix any issues.
  4. Root Color:

    • Ensure that the root of the tree is always black. If it's not, change its color to black.
  5. Complexity:

    • The worst-case time complexity for insertion in a Red-Black Tree is O(log n), where n is the number of nodes in the tree.

 

Code Examples

#1 Insertion in a Red-Black Tree implement in Python

Code - Python Programming

class Node:
    def __init__(self, key, color, left=None, right=None, parent=None):
        self.key = key
        self.color = color
        self.left = left
        self.right = right
        self.parent = parent


class RedBlackTree:
    def __init__(self):
        self.NIL = Node(None, 'black')  # NIL represents a null node in a Red-Black Tree
        self.root = self.NIL

    def insert(self, key):
        new_node = Node(key, 'red')
        self._insert(new_node)

    def _insert(self, z):
        y = self.NIL
        x = self.root

        while x != self.NIL:
            y = x
            if z.key < x.key:
                x = x.left
            else:
                x = x.right

        z.parent = y

        if y == self.NIL:
            self.root = z
        elif z.key < y.key:
            y.left = z
        else:
            y.right = z

        z.left = self.NIL
        z.right = self.NIL
        z.color = 'red'
        self._insert_fixup(z)

    def _insert_fixup(self, z):
        while z.parent.color == 'red':
            if z.parent == z.parent.parent.left:
                y = z.parent.parent.right
                if y.color == 'red':
                    z.parent.color = 'black'
                    y.color = 'black'
                    z.parent.parent.color = 'red'
                    z = z.parent.parent
                else:
                    if z == z.parent.right:
                        z = z.parent
                        self._left_rotate(z)
                    z.parent.color = 'black'
                    z.parent.parent.color = 'red'
                    self._right_rotate(z.parent.parent)
            else:
                y = z.parent.parent.left
                if y.color == 'red':
                    z.parent.color = 'black'
                    y.color = 'black'
                    z.parent.parent.color = 'red'
                    z = z.parent.parent
                else:
                    if z == z.parent.left:
                        z = z.parent
                        self._right_rotate(z)
                    z.parent.color = 'black'
                    z.parent.parent.color = 'red'
                    self._left_rotate(z.parent.parent)

        self.root.color = 'black'

    def _left_rotate(self, x):
        y = x.right
        x.right = y.left

        if y.left != self.NIL:
            y.left.parent = x

        y.parent = x.parent

        if x.parent == self.NIL:
            self.root = y
        elif x == x.parent.left:
            x.parent.left = y
        else:
            x.parent.right = y

        y.left = x
        x.parent = y

    def _right_rotate(self, y):
        x = y.left
        y.left = x.right

        if x.right != self.NIL:
            x.right.parent = y

        x.parent = y.parent

        if y.parent == self.NIL:
            self.root = x
        elif y == y.parent.left:
            y.parent.left = x
        else:
            y.parent.right = x

        x.right = y
        y.parent = x

# Example usage:
rb_tree = RedBlackTree()
keys = [10, 20, 30, 15, 25, 5]
for key in keys:
    rb_tree.insert(key)
Copy The Code & Try With Live Editor

#2 Insertion in a Red-Black Tree implement in Java

Code - Java Programming

enum Color {
    RED,
    BLACK
}

class Node {
    int key;
    Node left, right, parent;
    Color color;

    public Node(int key) {
        this.key = key;
        this.color = Color.RED; // New nodes are always red initially
    }
}

public class RedBlackTree {
    private Node root;
    private Node nil; // Represents null in the original algorithm

    public RedBlackTree() {
        nil = new Node(-1);
        nil.color = Color.BLACK;
        root = nil;
    }

    // Other Red-Black Tree methods...

    public void insert(int key) {
        Node newNode = new Node(key);
        insertNode(newNode);
        fixInsert(newNode);
    }

    private void insertNode(Node newNode) {
        Node parent = nil;
        Node current = root;

        while (current != nil) {
            parent = current;
            if (newNode.key  <  current.key) {
                current = current.left;
            } else {
                current = current.right;
            }
        }

        newNode.parent = parent;

        if (parent == nil) {
            root = newNode; // Tree was empty
        } else if (newNode.key  <  parent.key) {
            parent.left = newNode;
        } else {
            parent.right = newNode;
        }

        newNode.left = nil;
        newNode.right = nil;
        newNode.color = Color.RED; // New nodes are always red initially
    }

    private void fixInsert(Node newNode) {
        while (newNode.parent.color == Color.RED) {
            if (newNode.parent == newNode.parent.parent.left) {
                Node uncle = newNode.parent.parent.right;

                if (uncle.color == Color.RED) {
                    newNode.parent.color = Color.BLACK;
                    uncle.color = Color.BLACK;
                    newNode.parent.parent.color = Color.RED;
                    newNode = newNode.parent.parent;
                } else {
                    if (newNode == newNode.parent.right) {
                        newNode = newNode.parent;
                        leftRotate(newNode);
                    }

                    newNode.parent.color = Color.BLACK;
                    newNode.parent.parent.color = Color.RED;
                    rightRotate(newNode.parent.parent);
                }
            } else {
                Node uncle = newNode.parent.parent.left;

                if (uncle.color == Color.RED) {
                    newNode.parent.color = Color.BLACK;
                    uncle.color = Color.BLACK;
                    newNode.parent.parent.color = Color.RED;
                    newNode = newNode.parent.parent;
                } else {
                    if (newNode == newNode.parent.left) {
                        newNode = newNode.parent;
                        rightRotate(newNode);
                    }

                    newNode.parent.color = Color.BLACK;
                    newNode.parent.parent.color = Color.RED;
                    leftRotate(newNode.parent.parent);
                }
            }
        }

        root.color = Color.BLACK;
    }

    // Left Rotation
    private void leftRotate(Node x) {
        Node y = x.right;
        x.right = y.left;

        if (y.left != nil) {
            y.left.parent = x;
        }

        y.parent = x.parent;

        if (x.parent == nil) {
            root = y;
        } else if (x == x.parent.left) {
            x.parent.left = y;
        } else {
            x.parent.right = y;
        }

        y.left = x;
        x.parent = y;
    }

    // Right Rotation
    private void rightRotate(Node y) {
        Node x = y.left;
        y.left = x.right;

        if (x.right != nil) {
            x.right.parent = y;
        }

        x.parent = y.parent;

        if (y.parent == nil) {
            root = x;
        } else if (y == y.parent.right) {
            y.parent.right = x;
        } else {
            y.parent.left = x;
        }

        x.right = y;
        y.parent = x;
    }

    // Other Red-Black Tree methods...
}
Copy The Code & Try With Live Editor

#3 Insertion in a Red-Black Tree implement in C

Code - C Programming

#include <stdio.h>
#include <stdlib.h>

// Node structure for Red-Black Tree
typedef struct Node {
    int key;
    char color; // 'R' for red, 'B' for black
    struct Node* parent;
    struct Node* left;
    struct Node* right;
} Node;

// Function to perform left rotation
void leftRotate(Node** root, 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)
        *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(Node** root, 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)
        *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 fixInsert(Node** root, Node* z) {
    while (z != *root && z->parent->color == 'R') {
        if (z->parent == z->parent->parent->left) {
            Node* y = z->parent->parent->right;

            if (y != NULL && y->color == 'R') {
                z->parent->color = 'B';
                y->color = 'B';
                z->parent->parent->color = 'R';
                z = z->parent->parent;
            } else {
                if (z == z->parent->right) {
                    z = z->parent;
                    leftRotate(root, z);
                }

                z->parent->color = 'B';
                z->parent->parent->color = 'R';
                rightRotate(root, z->parent->parent);
            }
        } else {
            // Symmetric case (left is replaced with right)
            Node* y = z->parent->parent->left;

            if (y != NULL && y->color == 'R') {
                z->parent->color = 'B';
                y->color = 'B';
                z->parent->parent->color = 'R';
                z = z->parent->parent;
            } else {
                if (z == z->parent->left) {
                    z = z->parent;
                    rightRotate(root, z);
                }

                z->parent->color = 'B';
                z->parent->parent->color = 'R';
                leftRotate(root, z->parent->parent);
            }
        }
    }

    (*root)->color = 'B';
}

// Function to insert a key into Red-Black Tree
void insertRBTree(Node** root, int key) {
    // Create a new node
    Node* z = (Node*)malloc(sizeof(Node));
    z->key = key;
    z->left = z->right = z->parent = NULL;
    z->color = 'R';

    // BST insert
    Node* y = NULL;
    Node* x = *root;

    while (x != NULL) {
        y = x;
        if (z->key  <  x->key)
            x = x->left;
        else
            x = x->right;
    }

    z->parent = y;
    if (y == NULL)
        *root = z;
    else if (z->key  <  y->key)
        y->left = z;
    else
        y->right = z;

    // Fix Red-Black Tree properties
    fixInsert(root, z);
}

// Function to print Red-Black Tree in-order
void inOrderTraversal(Node* root) {
    if (root != NULL) {
        inOrderTraversal(root->left);
        printf("(%d, %c) ", root->key, root->color);
        inOrderTraversal(root->right);
    }
}

// Function to free memory allocated for Red-Black Tree
void freeRBTree(Node* root) {
    if (root != NULL) {
        freeRBTree(root->left);
        freeRBTree(root->right);
        free(root);
    }
}

int main() {
    Node* root = NULL;

    // Insert keys into Red-Black Tree
    int keys[] = {7, 3, 18, 10, 22, 8, 11, 26};
    int n = sizeof(keys) / sizeof(keys[0]);

    for (int i = 0; i  <  n; i++) {
        insertRBTree(&root, keys[i]);
        printf("Inserted %d: In-order Traversal: ", keys[i]);
        inOrderTraversal(root);
        printf("\n");
    }

    // Free memory
    freeRBTree(root);

    return 0;
}
Copy The Code & Try With Live Editor

#4 Insertion in a Red-Black Tree implement in C++

Code - C++ Programming

#include <iostream>

enum Color { RED, BLACK };

template  < typename T>
struct Node {
    T data;
    Color color;
    Node* parent;
    Node* left;
    Node* right;

    Node(T val) : data(val), color(RED), parent(nullptr), left(nullptr), right(nullptr) {}
};

template  < typename T>
class RedBlackTree {
private:
    Node* root;

    // Helper functions
    void leftRotate(Node* x);
    void rightRotate(Node < T>* x);
    void insertFixup(Node* z);

public:
    RedBlackTree() : root(nullptr) {}

    // Public function to insert a value into the Red-Black Tree
    void insert(T val);
};

// Left rotation in the Red-Black Tree
template  < typename T>
void RedBlackTree::leftRotate(Node* x) {
    Node* y = x->right;
    x->right = y->left;

    if (y->left != nullptr) {
        y->left->parent = x;
    }

    y->parent = x->parent;

    if (x->parent == nullptr) {
        root = y;
    } else if (x == x->parent->left) {
        x->parent->left = y;
    } else {
        x->parent->right = y;
    }

    y->left = x;
    x->parent = y;
}

// Right rotation in the Red-Black Tree
template  < typename T>
void RedBlackTree::rightRotate(Node* x) {
    Node* y = x->left;
    x->left = y->right;

    if (y->right != nullptr) {
        y->right->parent = x;
    }

    y->parent = x->parent;

    if (x->parent == nullptr) {
        root = y;
    } else if (x == x->parent->left) {
        x->parent->left = y;
    } else {
        x->parent->right = y;
    }

    y->right = x;
    x->parent = y;
}

// Fix the Red-Black Tree properties after inserting a node
template  < typename T>
void RedBlackTree::insertFixup(Node* z) {
    while (z->parent != nullptr && z->parent->color == RED) {
        if (z->parent == z->parent->parent->left) {
            Node* y = z->parent->parent->right;

            if (y != nullptr && y->color == RED) {
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            } else {
                if (z == z->parent->right) {
                    z = z->parent;
                    leftRotate(z);
                }

                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                rightRotate(z->parent->parent);
            }
        } else {
            Node < T>* y = z->parent->parent->left;

            if (y != nullptr && y->color == RED) {
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            } else {
                if (z == z->parent->left) {
                    z = z->parent;
                    rightRotate(z);
                }

                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                leftRotate(z->parent->parent);
            }
        }
    }

    root->color = BLACK;
}

// Public function to insert a value into the Red-Black Tree
template  < typename T>
void RedBlackTree::insert(T val) {
    Node* z = new Node(val);
    Node* y = nullptr;
    Node < T>* x = root;

    while (x != nullptr) {
        y = x;

        if (z->data  <  x->data) {
            x = x->left;
        } else {
            x = x->right;
        }
    }

    z->parent = y;

    if (y == nullptr) {
        root = z;
    } else if (z->data  <  y->data) {
        y->left = z;
    } else {
        y->right = z;
    }

    insertFixup(z);
}

int main() {
    RedBlackTree < int> rbt;

    // Inserting values into the Red-Black Tree
    rbt.insert(10);
    rbt.insert(20);
    rbt.insert(30);
    rbt.insert(15);
    rbt.insert(25);

    // You can perform other operations on the Red-Black Tree as needed

    return 0;
}
Copy The Code & Try With Live Editor
Advertisements

Demonstration


Insertion in a Red-Black Tree-DevsEnv