C Program for Red Black Tree Insertion - GeeksforGeeks

16 Sep, 2021
Following article is extension of article discussed here.In AVL tree insertion, we used rotation as a tool to do balancing after insertion caused imbalance. In Red-Black tree, we use two tools to do balancing.1) Recoloring 2) Rotation
We try recoloring first, if recoloring doesn’t work, then we go for rotation. Following is detailed algorithm. The algorithms has mainly two cases depending upon the color of uncle. If uncle is red, we do recoloring. If uncle is black, we do rotations and/or recoloring.Color of a NULL node is considered as BLACK.
Let x be the newly inserted node. 1. Perform standard BST insertion and make the color of newly inserted nodes as RED.2. If x is root, change color of x as BLACK (Black height of complete tree increases by 1).3. Do following if color of x’s parent is not BLACK or x is not root.      1. If x’s uncle is RED (Grand parent must have been black from property 4)          1. Change color of parent and uncle as BLACK.          2. color of grand parent as RED.          3. Change x = x’s grandparent, repeat steps 2 and 3 for new x.  
      2. If x’s uncle is BLACK, then there can be four configurations for x, x’s parent (p) and x’s grandparent (g) (This is similar to AVL Tree) 
        1. Determine the configuration:
             1. Left Left Case (p is left child of g and x is left child of p).
              2.Left Right Case (p is left child of g and x is right child of p).
              3. Right Right Case (Mirror of case a).
              4.Right Left Case (Mirror of case c).
         2. Change x = x’s parent, repeat steps 2 and 3 for new x.
Following are operations to be performed in four subcases when uncle is BLACK.
Left Left Case (See g, p and x) 
Left Right Case (See g, p and x) 
Right Right Case (See g, p and x) 
Right Left Case (See g, p and x) 
Examples of Insertion 
Below is C++ Code.
C++
C
/** C++ implementation for   Red-Black Tree Insertion   This code is adopted from   the code provided by   Dinesh Khandelwal in comments **/#include <bits/stdc++.h>using namespace std; enum Color {RED, BLACK}; struct Node{    int data;    bool color;    Node *left, *right, *parent;     // Constructor    Node(int data)    {       this->data = data;       left = right = parent = NULL;       this->color = RED;    }}; // Class to represent Red-Black Treeclass RBTree{private:    Node *root;protected:    void rotateLeft(Node *&, Node *&);    void rotateRight(Node *&, Node *&);    void fixViolation(Node *&, Node *&);public:    // Constructor    RBTree() { root = NULL; }    void insert(const int &n);    void inorder();    void levelOrder();}; // A recursive function to do inorder traversalvoid inorderHelper(Node *root){    if (root == NULL)        return;     inorderHelper(root->left);    cout << root->data << "  ";    inorderHelper(root->right);} /* A utility function to insert    a new node with given key   in BST */Node* BSTInsert(Node* root, Node *pt){    /* If the tree is empty, return a new node */    if (root == NULL)       return pt;     /* Otherwise, recur down the tree */    if (pt->data < root->data)    {        root->left  = BSTInsert(root->left, pt);        root->left->parent = root;    }    else if (pt->data > root->data)    {        root->right = BSTInsert(root->right, pt);        root->right->parent = root;    }     /* return the (unchanged) node pointer */    return root;} // Utility function to do level order traversalvoid levelOrderHelper(Node *root){    if (root == NULL)        return;     std::queue<Node *> q;    q.push(root);     while (!q.empty())    {        Node *temp = q.front();        cout << temp->data << "  ";        q.pop();         if (temp->left != NULL)            q.push(temp->left);         if (temp->right != NULL)            q.push(temp->right);    }} void RBTree::rotateLeft(Node *&root, Node *&pt){    Node *pt_right = pt->right;     pt->right = pt_right->left;     if (pt->right != NULL)        pt->right->parent = pt;     pt_right->parent = pt->parent;     if (pt->parent == NULL)        root = pt_right;     else if (pt == pt->parent->left)        pt->parent->left = pt_right;     else        pt->parent->right = pt_right;     pt_right->left = pt;    pt->parent = pt_right;} void RBTree::rotateRight(Node *&root, Node *&pt){    Node *pt_left = pt->left;     pt->left = pt_left->right;     if (pt->left != NULL)        pt->left->parent = pt;     pt_left->parent = pt->parent;     if (pt->parent == NULL)        root = pt_left;     else if (pt == pt->parent->left)        pt->parent->left = pt_left;     else        pt->parent->right = pt_left;     pt_left->right = pt;    pt->parent = pt_left;} // This function fixes violations// caused by BST insertionvoid RBTree::fixViolation(Node *&root, Node *&pt){    Node *parent_pt = NULL;    Node *grand_parent_pt = NULL;     while ((pt != root) && (pt->color != BLACK) &&           (pt->parent->color == RED))    {         parent_pt = pt->parent;        grand_parent_pt = pt->parent->parent;         /*  Case : A            Parent of pt is left child            of Grand-parent of pt */        if (parent_pt == grand_parent_pt->left)        {             Node *uncle_pt = grand_parent_pt->right;             /* Case : 1               The uncle of pt is also red               Only Recoloring required */            if (uncle_pt != NULL && uncle_pt->color ==                                                   RED)            {                grand_parent_pt->color = RED;                parent_pt->color = BLACK;                uncle_pt->color = BLACK;                pt = grand_parent_pt;            }             else            {                /* Case : 2                   pt is right child of its parent                   Left-rotation required */                if (pt == parent_pt->right)                {                    rotateLeft(root, parent_pt);                    pt = parent_pt;                    parent_pt = pt->parent;                }                 /* Case : 3                   pt is left child of its parent                   Right-rotation required */                rotateRight(root, grand_parent_pt);                swap(parent_pt->color,                           grand_parent_pt->color);                pt = parent_pt;            }        }         /* Case : B           Parent of pt is right child           of Grand-parent of pt */        else        {            Node *uncle_pt = grand_parent_pt->left;             /*  Case : 1                The uncle of pt is also red                Only Recoloring required */            if ((uncle_pt != NULL) && (uncle_pt->color ==                                                    RED))            {                grand_parent_pt->color = RED;                parent_pt->color = BLACK;                uncle_pt->color = BLACK;                pt = grand_parent_pt;            }            else            {                /* Case : 2                   pt is left child of its parent                   Right-rotation required */                if (pt == parent_pt->left)                {                    rotateRight(root, parent_pt);                    pt = parent_pt;                    parent_pt = pt->parent;                }                 /* Case : 3                   pt is right child of its parent                   Left-rotation required */                rotateLeft(root, grand_parent_pt);                swap(parent_pt->color,                         grand_parent_pt->color);                pt = parent_pt;            }        }    }     root->color = BLACK;} // Function to insert a new node with given datavoid RBTree::insert(const int &data){    Node *pt = new Node(data);     // Do a normal BST insert    root = BSTInsert(root, pt);     // fix Red Black Tree violations    fixViolation(root, pt);} // Function to do inorder and level order traversalsvoid RBTree::inorder()     {  inorderHelper(root);}void RBTree::levelOrder()  {  levelOrderHelper(root); } // Driver Codeint main(){    RBTree tree;     tree.insert(7);    tree.insert(6);    tree.insert(5);    tree.insert(4);    tree.insert(3);    tree.insert(2);    tree.insert(1);     cout << "Inorder Traversal of Created Tree\n";    tree.inorder();     cout << "\n\nLevel Order Traversal of Created Tree\n";    tree.levelOrder();     return 0;}
/** C implementation for    Red-Black Tree Insertion    This code is provided by    costheta_z **/#include <stdio.h>#include <stdlib.h> // Structure to represent each// node in a red-black treestruct node {    int d; // data    int c; // 1-red, 0-black    struct node* p; // parent    struct node* r; // right-child    struct node* l; // left child}; // global root for the entire treestruct node* root = NULL; // function to perform BST insertion of a nodestruct node* bst(struct node* trav,                      struct node* temp){    // If the tree is empty,    // return a new node    if (trav == NULL)        return temp;     // Otherwise recur down the tree    if (temp->d < trav->d)    {        trav->l = bst(trav->l, temp);        trav->l->p = trav;    }    else if (temp->d > trav->d)    {        trav->r = bst(trav->r, temp);        trav->r->p = trav;    }     // Return the (unchanged) node pointer    return trav;} // Function performing right rotation// of the passed nodevoid rightrotate(struct node* temp){    struct node* left = temp->l;    temp->l = left->r;    if (temp->l)        temp->l->p = temp;    left->p = temp->p;    if (!temp->p)        root = left;    else if (temp == temp->p->l)        temp->p->l = left;    else        temp->p->r = left;    left->r = temp;    temp->p = left;} // Function performing left rotation// of the passed nodevoid leftrotate(struct node* temp){    struct node* right = temp->r;    temp->r = right->l;    if (temp->r)        temp->r->p = temp;    right->p = temp->p;    if (!temp->p)        root = right;    else if (temp == temp->p->l)        temp->p->l = right;    else        temp->p->r = right;    right->l = temp;    temp->p = right;} // This function fixes violations// caused by BST insertionvoid fixup(struct node* root, struct node* pt){    struct node* parent_pt = NULL;    struct node* grand_parent_pt = NULL;     while ((pt != root) && (pt->c != 0)           && (pt->p->c == 1))    {        parent_pt = pt->p;        grand_parent_pt = pt->p->p;         /*  Case : A             Parent of pt is left child             of Grand-parent of           pt */        if (parent_pt == grand_parent_pt->l)        {             struct node* uncle_pt = grand_parent_pt->r;             /* Case : 1                The uncle of pt is also red                Only Recoloring required */            if (uncle_pt != NULL && uncle_pt->c == 1)            {                grand_parent_pt->c = 1;                parent_pt->c = 0;                uncle_pt->c = 0;                pt = grand_parent_pt;            }             else {                 /* Case : 2                     pt is right child of its parent                     Left-rotation required */                if (pt == parent_pt->r) {                    leftrotate(parent_pt);                    pt = parent_pt;                    parent_pt = pt->p;                }                 /* Case : 3                     pt is left child of its parent                     Right-rotation required */                rightrotate(grand_parent_pt);                int t = parent_pt->c;                parent_pt->c = grand_parent_pt->c;                grand_parent_pt->c = t;                pt = parent_pt;            }        }         /* Case : B             Parent of pt is right             child of Grand-parent of           pt */        else {            struct node* uncle_pt = grand_parent_pt->l;             /*  Case : 1                The uncle of pt is also red                Only Recoloring required */            if ((uncle_pt != NULL) && (uncle_pt->c == 1))            {                grand_parent_pt->c = 1;                parent_pt->c = 0;                uncle_pt->c = 0;                pt = grand_parent_pt;            }            else {                /* Case : 2                   pt is left child of its parent                   Right-rotation required */                if (pt == parent_pt->l) {                    rightrotate(parent_pt);                    pt = parent_pt;                    parent_pt = pt->p;                }                 /* Case : 3                     pt is right child of its parent                     Left-rotation required */                leftrotate(grand_parent_pt);                int t = parent_pt->c;                parent_pt->c = grand_parent_pt->c;                grand_parent_pt->c = t;                pt = parent_pt;            }        }    }     root->c = 0;} // Function to print inorder traversal// of the fixated treevoid inorder(struct node* trav){    if (trav == NULL)        return;    inorder(trav->l);    printf("%d ", trav->d);    inorder(trav->r);} // driver codeint main(){    int n = 7;    int a[7] = { 7, 6, 5, 4, 3, 2, 1 };     for (int i = 0; i < n; i++) {         // allocating memory to the node and initializing:        // 1. color as red        // 2. parent, left and right pointers as NULL        // 3. data as i-th value in the array        struct node* temp            = (struct node*)malloc(sizeof(struct node));        temp->r = NULL;        temp->l = NULL;        temp->p = NULL;        temp->d = a[i];        temp->c = 1;         // calling function that performs bst insertion of        // this newly created node        root = bst(root, temp);         // calling function to preserve properties of rb        // tree        fixup(root, temp);    }     printf("Inorder Traversal of Created Tree\n");    inorder(root);     return 0;}
Output: 
Inorder Traversal of Created Tree
1  2  3  4  5  6  7  

Level Order Traversal of Created Tree
6  4  7  2  5  1  3   
YouTubeGeeksforGeeks507K subscribersRed Black Tree (Insertion) | GeeksforGeeksWatch laterShareCopy linkInfoShoppingTap to unmuteIf playback doesn't begin shortly, try restarting your device.You're signed outVideos you watch may be added to the TV's watch history and influence TV recommendations. To avoid this, cancel and sign in to YouTube on your computer.CancelConfirmMore videosMore videosSwitch cameraShareInclude playlistAn error occurred while retrieving sharing information. Please try again later.Watch on0:000:000:00 / 4:26•Live•<div class="player-unavailable"><h1 class="message">An error occurred.</h1><div class="submessage"><a href="https://www.youtube.com/watch?v=YCo2-H2CL6Q" target="_blank">Try watching this video on www.youtube.com</a>, or enable JavaScript if it is disabled in your browser.</div></div>
This article is contributed by Mohsin Mohammaad. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
Shlomi Elhaiani
costheta_z
saurabh1990aror
Red Black Tree
Self-Balancing-BST
Binary Search Tree
Binary Search Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Sorted Array to Balanced BST
Optimal Binary Search Tree | DP-24
Inorder Successor in Binary Search Tree
Find the node with minimum value in a Binary Search Tree
Overview of Data Structures | Set 2 (Binary Tree, BST, Heap and Hash)
Difference between Binary Tree and Binary Search Tree
Lowest Common Ancestor in a Binary Search Tree.
Binary Tree to Binary Search Tree Conversion
Find k-th smallest element in BST (Order Statistics in BST)
Convert a normal BST to Balanced BST