Skip to content
Related Articles

Related Articles

Improve Article

Left Leaning Red Black Tree (Insertion)

  • Difficulty Level : Hard
  • Last Updated : 07 Jul, 2021

Prerequisites : Red – Black Trees.
A left leaning Red Black Tree or (LLRB), is a variant of red black tree, which is a lot easier to implement than Red black tree itself and guarantees all the search, delete and insert operations in O(logn) time.

Which nodes are RED and Which are Black ? 
Nodes which have double incoming edge are RED in color. 
Nodes which have single incoming edge are BLACK in color.

Characteristics of LLRB 
1. Root node is Always BLACK in color. 
2. Every new Node inserted is always RED in color. 
3. Every NULL child of a node is considered as BLACK in color. 
Eg : only 40 is present in tree. 

 
     root
       |
       40 <-- as 40 is the root so it 
      /  \    is also Black in color. 
    NULL  NULL <-- Black in color.

4. There should not be a node which has RIGHT RED child and LEFT BLACK child(or NULL child as all NULLS are BLACK), if present Left rotate the node, and swap the colors of current node and its LEFT child so as to maintain consistency for rule 2 i.e., new node must be RED in color. 

 CASE 1.
   root                        root     
     |                          ||      
     40      LeftRotate(40)     50     
    /  \\        --->          /  \    
  NULL  50                   40   NULL    

                               root              
                                |               
         ColorSwap(50, 40)      50 
           --->               //  \              
                             40  NULL                     

5. There should not be a node which has LEFT RED child and LEFT RED grandchild, if present Right Rotate the node and swap the colors between node and it’s RIGHT child to follow rule 2. 



  CASE 2.
   root                         root      
    |                            ||        
    40        RightRotate(40)    20        
   //  \         --->          //   \      
  20    50                    10    40           
 //                                   \      
10                                     50

                          root
                           |
    ColorSwap(20, 40)      20
      --->                // \\
                         10   40
                               \
                               50
 

6. There should not be a node which has LEFT RED child and RIGHT RED child, if present Invert the colors of all nodes i. e., current_node, LEFT child, and RIGHT child. 

   CASE 3.
   root                           root      
    |       !color(20, 10, 30)     ||       
    20            --->             20                
  //  \\                          /  \  
 10    30                        10  30 

                                     root
        As the root is always black    |                     
                --->                  20   
                                     /  \
                                   10   30   

Why are we following the above mentioned rules? Because by following above characteristics/rules we are able to simulate all the red-black tree’s properties without caring about the complex implementation of it. 

Example: 

Insert the following data into LEFT LEANING RED-BLACK
TREE and display the inorder traversal of tree.
Input : 10 20 30 40 50 25
Output : 10 20 30 40 50 25
        root
         |
         40
       //  \
      20    50
     /  \
   10    30
        //
       25 

Approach : 
Insertions in the LLRB is exactly like inserting into a Binary search tree . The difference is that that After we insert the node into the tree we will retrace our steps back to root and try to enforce the above rules for LLRB. 
While doing the above rotations and swapping of color it may happen that our root becomes RED in color so we also. We have to make sure that our root remains always BLACK in color. 

LLRB insertion Example.

C++




// C++ program to implement insert operation
// in Red Black Tree.
#include <bits/stdc++.h>
using namespace std;
 
typedef struct node
{
    struct node *left, *right;
    int data;
     
    // red ==> true, black ==> false
    bool color;
     
}node;
 
// Utility function to create a node.
node* createNode(int data, bool color)
{
    node *myNode = new node();
    myNode -> left = myNode -> right = NULL;
    myNode -> data = data;
 
    // New Node which is created is
    // always red in color.
    myNode -> color = true;
    return myNode;
}
 
// Utility function to rotate node anticlockwise.
node* rotateLeft(node* myNode)
{
    cout << "left rotation!!\n";
    node *child = myNode -> right;
    node *childLeft = child -> left;
 
    child -> left = myNode;
    myNode -> right = childLeft;
 
    return child;
}
 
// Utility function to rotate node clockwise.
node* rotateRight(node* myNode)
{
    cout << "right rotation\n";
    node *child = myNode -> left;
    node *childRight =  child -> right;
 
    child -> right = myNode;
    myNode -> left = childRight;
     
    return child;
}
 
// Utility function to check whether
// node is red in color or not.
int isRed(node *myNode)
{
    if (myNode == NULL)
       return 0;
        
    return (myNode -> color == true);
}
 
// Utility function to swap color of two
// nodes.
void swapColors(node *node1, node *node2)
{
    bool temp = node1 -> color;
    node1 -> color = node2 -> color;
    node2 -> color = temp;
}
 
// Insertion into Left Leaning Red Black Tree.
node* insert(node* myNode, int data)
{
     
    // Normal insertion code for any Binary
    // Search tree.
    if (myNode == NULL)
        return createNode(data, false);   
 
    if (data < myNode -> data)
        myNode -> left = insert(myNode -> left, data);
 
    else if (data > myNode -> data)
        myNode -> right = insert(myNode -> right, data);
 
    else   
        return myNode;
         
    // case 1.
    // when right child is Red but left child is
    // Black or doesn't exist.
    if (isRed(myNode -> right) &&
       !isRed(myNode -> left))
    {
         
        // Left rotate the node to make it into
        // valid structure.
        myNode = rotateLeft(myNode);
 
        // Swap the colors as the child node
        // should always be red
        swapColors(myNode, myNode -> left);
    }
     
    // case 2
    // when left child as well as left grand
    // child in Red
    if (isRed(myNode -> left) &&
        isRed(myNode -> left -> left))
    {  
         
        // Right rotate the current node to make
        // it into a valid structure.
        myNode = rotateRight(myNode);
        swapColors(myNode, myNode -> right);
    }
     
    // case 3
    // when both left and right child are Red in color.
    if (isRed(myNode -> left) && isRed(myNode -> right))
    {
         
        // Invert the color of node as well
        // it's left and right child.
        myNode -> color = !myNode -> color;
 
        // Change the color to black.
        myNode -> left -> color = false;
        myNode -> right -> color = false;
    }
    return myNode;
}
 
// Inorder traversal
void inorder(node *node)
{
    if (node)
    {
        inorder(node -> left);
        cout<< node -> data << " ";
        inorder(node -> right);
    }
}
 
// Driver code
int main()
{
     
    node *root = NULL;
     
    /* LLRB tree made after all insertions are made.
             
    1. Nodes which have double INCOMING edge means
       that they are RED in color.
    2. Nodes which have single INCOMING edge means
       that they are BLACK in color.
     
        root
         |
         40
       //  \
      20    50
     /  \
    10    30
        //
       25    */
     
    root = insert(root, 10);
     
    // To make sure that root remains
    // black is color
    root -> color = false;
     
    root = insert(root, 20);
    root -> color = false;
     
    root = insert(root, 30);
    root -> color = false;
     
    root = insert(root, 40);
    root -> color = false;
     
    root = insert(root, 50);
    root -> color = false;
     
    root = insert(root, 25);
    root -> color = false;
     
    // Display the tree through inorder traversal.
    inorder(root);
     
    return 0;
}
 
// This code is contributed by rutvik_56

C




// C program to implement insert operation
// in Red Black Tree.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
 
typedef struct node
{
    struct node *left, *right;
    int data;
 
    // red ==> true, black ==> false
    bool color;
} node;
 
 
 
// utility function to create a node.
node* createNode(int data, bool color)
{
    node *myNode = (node *) malloc(sizeof(node));
    myNode -> left = myNode -> right = NULL;
    myNode -> data = data;
 
    // New Node which is created is
    // always red in color.
    myNode -> color = true;
    return myNode;
}
 
// utility function to rotate node anticlockwise.
node* rotateLeft(node* myNode)
{
    printf("left rotation!!\n");
    node *child = myNode -> right;
    node *childLeft = child -> left;
 
    child -> left = myNode;
    myNode -> right = childLeft;
 
    return child;
}
 
// utility function to rotate node clockwise.
node* rotateRight(node* myNode)
{
    printf("right rotation\n");
    node *child = myNode -> left;
    node *childRight =  child -> right;
 
    child -> right = myNode;
    myNode -> left = childRight;
     
    return child;
}
 
// utility function to check whether
// node is red in color or not.
int isRed(node *myNode)
{
    if (myNode == NULL)
       return 0;
    return (myNode -> color == true);
}
 
// utility function to swap color of two
// nodes.
void swapColors(node *node1, node *node2)
{
    bool temp = node1 -> color;
    node1 -> color = node2 -> color;
    node2 -> color = temp;
}
 
// insertion into Left Leaning Red Black Tree.
node* insert(node* myNode, int data)
{
    // Normal insertion code for any Binary
    // Search tree.
    if (myNode == NULL)
        return createNode(data, false);   
 
    if (data < myNode -> data)
        myNode -> left = insert(myNode -> left, data);
 
    else if (data > myNode -> data)
        myNode -> right = insert(myNode -> right, data);
 
    else   
        return myNode;
 
     
    // case 1.
    // when right child is Red but left child is
    // Black or doesn't exist.
    if (isRed(myNode -> right) && !isRed(myNode -> left))
    {
        // left rotate the node to make it into
        // valid structure.
        myNode = rotateLeft(myNode);
 
        // swap the colors as the child node
        // should always be red
        swapColors(myNode, myNode -> left);
         
    }
     
    // case 2
    // when left child as well as left grand child in Red
    if (isRed(myNode -> left) && isRed(myNode -> left -> left))
    {  
        // right rotate the current node to make
        // it into a valid structure.
        myNode = rotateRight(myNode);
        swapColors(myNode, myNode -> right);
    }
     
     
    // case 3
    // when both left and right child are Red in color.
    if (isRed(myNode -> left) && isRed(myNode -> right))
    {
        // invert the color of node as well
        // it's left and right child.
        myNode -> color = !myNode -> color;
 
        // change the color to black.
        myNode -> left -> color = false;
        myNode -> right -> color = false;
    }
 
    return myNode;
}
 
// Inorder traversal
void inorder(node *node)
{
    if (node)
    {
        inorder(node -> left);
        printf("%d ", node -> data);
        inorder(node -> right);
    }
}
 
// Driver function
int main()
{
    node *root = NULL;
    /* LLRB tree made after all insertions are made.
             
    1. Nodes which have double INCOMING edge means
       that they are RED in color.
    2. Nodes which have single INCOMING edge means
       that they are BLACK in color.
     
        root
         |
         40
       //  \
      20    50
     /  \
   10    30
        //
       25    */
 
    root = insert(root, 10);
    // to make sure that root remains
    // black is color
    root -> color = false;
     
    root = insert(root, 20);
    root -> color = false;
     
    root = insert(root, 30);
    root -> color = false;
    
    root = insert(root, 40);
    root -> color = false;
     
    root = insert(root, 50);
    root -> color = false;
     
    root = insert(root, 25);
    root -> color = false;
 
    // display the tree through inorder traversal.
    inorder(root);
     
    return 0;
}

Java




// Java program to implement insert operation
// in Red Black Tree.
 
class node
{
    node left, right;
    int data;
 
    // red ==> true, black ==> false
    boolean color;
     
    node(int data)
    {
        this.data = data;
        left = null;
        right = null;
         
        // New Node which is created is
        // always red in color.
        color = true;
    }
}
 
public class LLRBTREE {
 
    private static node root = null;
     
    // utility function to rotate node anticlockwise.
    node rotateLeft(node myNode)
    {
        System.out.printf("left rotation!!\n");
        node child = myNode.right;
        node childLeft = child.left;
 
        child.left = myNode;
        myNode.right = childLeft;
 
        return child;
    }
 
    // utility function to rotate node clockwise.
    node rotateRight(node myNode)
    {
        System.out.printf("right rotation\n");
        node child = myNode.left;
        node childRight = child.right;
 
        child.right = myNode;
        myNode.left = childRight;
 
        return child;
    }
 
    // utility function to check whether
    // node is red in color or not.
    boolean isRed(node myNode)
    {
        if (myNode == null)
            return false;
        return (myNode.color == true);
    }
 
    // utility function to swap color of two
    // nodes.
    void swapColors(node node1, node node2)
    {
        boolean temp = node1.color;
        node1.color = node2.color;
        node2.color = temp;
    }
 
    // insertion into Left Leaning Red Black Tree.
    node insert(node myNode, int data)
    {
        // Normal insertion code for any Binary
        // Search tree.
        if (myNode == null)
            return new node(data);
 
        if (data < myNode.data)
            myNode.left = insert(myNode.left, data);
         
        else if (data > myNode.data)
            myNode.right = insert(myNode.right, data);
         
        else
            return myNode;
 
 
        // case 1.
        // when right child is Red but left child is
        // Black or doesn't exist.
        if (isRed(myNode.right) && !isRed(myNode.left))
        {
            // left rotate the node to make it into
            // valid structure.
            myNode = rotateLeft(myNode);
 
            // swap the colors as the child node
            // should always be red
            swapColors(myNode, myNode.left);
 
        }
 
        // case 2
        // when left child as well as left grand child in Red
        if (isRed(myNode.left) && isRed(myNode.left.left))
        {
            // right rotate the current node to make
            // it into a valid structure.
            myNode = rotateRight(myNode);
            swapColors(myNode, myNode.right);
        }
 
 
        // case 3
        // when both left and right child are Red in color.
        if (isRed(myNode.left) && isRed(myNode.right))
        {
            // invert the color of node as well
            // it's left and right child.
            myNode.color = !myNode.color;
 
            // change the color to black.
            myNode.left.color = false;
            myNode.right.color = false;
        }
 
        return myNode;
    }
 
 
    // Inorder traversal
    void inorder(node node)
    {
        if (node != null)
        {
            inorder(node.left);
            System.out.print(node.data + " ");
            inorder(node.right);
        }
    }
 
    public static void main(String[] args) {
    /* LLRB tree made after all insertions are made.
             
    1. Nodes which have double INCOMING edge means
        that they are RED in color.
    2. Nodes which have single INCOMING edge means
        that they are BLACK in color.
     
        root
        |
        40
        // \
    20 50
    / \
    10 30
        //
        25 */
     
    LLRBTREE node = new LLRBTREE();
     
    root = node.insert(root, 10);
    // to make sure that root remains
    // black is color
    root.color = false;
     
    root = node.insert(root, 20);
    root.color = false;
     
    root = node.insert(root, 30);
    root.color = false;
     
    root = node.insert(root, 40);
    root.color = false;
     
    root = node.insert(root, 50);
    root.color = false;
     
    root = node.insert(root, 25);
    root.color = false;
 
    // display the tree through inorder traversal.
    node.inorder(root);
 
    }
     
}
 
// This code is contributed by ARSHPREET_SINGH

C#




// C# program to implement insert
// operation in Red Black Tree.
using System;
 
class node
{
    public node left, right;
    public int data;
 
    // red ==> true, black ==> false
    public Boolean color;
     
    public node(int data)
    {
        this.data = data;
        left = null;
        right = null;
         
        // New Node which is created
        // is always red in color.
        color = true;
    }
}
 
public class LLRBTREE
{
 
private static node root = null;
 
// utility function to rotate
// node anticlockwise.
node rotateLeft(node myNode)
{
    Console.Write("left rotation!!\n");
    node child = myNode.right;
    node childLeft = child.left;
 
    child.left = myNode;
    myNode.right = childLeft;
 
    return child;
}
 
// utility function to rotate
// node clockwise.
node rotateRight(node myNode)
{
    Console.Write("right rotation\n");
    node child = myNode.left;
    node childRight = child.right;
 
    child.right = myNode;
    myNode.left = childRight;
 
    return child;
}
 
// utility function to check whether
// node is red in color or not.
Boolean isRed(node myNode)
{
    if (myNode == null)
        return false;
    return (myNode.color == true);
}
 
// utility function to swap
// color of two nodes.
void swapColors(node node1, node node2)
{
    Boolean temp = node1.color;
    node1.color = node2.color;
    node2.color = temp;
}
 
// insertion into Left
// Leaning Red Black Tree.
node insert(node myNode, int data)
{
    // Normal insertion code for
    // any Binary Search tree.
    if (myNode == null)
        return new node(data);
 
    if (data < myNode.data)
        myNode.left = insert(myNode.left, data);
     
    else if (data > myNode.data)
        myNode.right = insert(myNode.right, data);
     
    else
        return myNode;
 
 
    // case 1.
    // when right child is Red
    // but left child is
    // Black or doesn't exist.
    if (isRed(myNode.right) &&
        !isRed(myNode.left))
    {
        // left rotate the node to make
        // it into valid structure.
        myNode = rotateLeft(myNode);
 
        // swap the colors as the child
        // node should always be red
        swapColors(myNode, myNode.left);
 
    }
 
    // case 2
    // when left child as well as
    // left grand child in Red
    if (isRed(myNode.left) &&
        isRed(myNode.left.left))
    {
        // right rotate the current node
        // to make it into a valid structure.
        myNode = rotateRight(myNode);
        swapColors(myNode, myNode.right);
    }
 
 
    // case 3
    // when both left and right
    // child are Red in color.
    if (isRed(myNode.left) &&
        isRed(myNode.right))
    {
        // invert the color of node as well
        // it's left and right child.
        myNode.color = !myNode.color;
 
        // change the color to black.
        myNode.left.color = false;
        myNode.right.color = false;
    }
 
    return myNode;
}
 
 
// Inorder traversal
void inorder(node node)
{
    if (node != null)
    {
        inorder(node.left);
        Console.Write(node.data + " ");
        inorder(node.right);
    }
}
 
// Driver Code
static public void Main(String []args)
{
/* LLRB tree made after all
   insertions are made.
         
1. Nodes which have double INCOMING
   edge means that they are RED in color.
2. Nodes which have single INCOMING edge 
   means that they are BLACK in color.
 
            root
             |
             40
           //   \
          20    50
        /    \
       10    30
            //
           25
*/
 
LLRBTREE node = new LLRBTREE();
 
root = node.insert(root, 10);
 
// to make sure that root 
// remains black is color
root.color = false;
 
root = node.insert(root, 20);
root.color = false;
 
root = node.insert(root, 30);
root.color = false;
 
root = node.insert(root, 40);
root.color = false;
 
root = node.insert(root, 50);
root.color = false;
 
root = node.insert(root, 25);
root.color = false;
 
// display the tree through
// inorder traversal.
node.inorder(root);
}
}
 
// This code is contributed
// by Arnab Kundu

Javascript




<script>
// Javascript program to implement insert operation
// in Red Black Tree.
 class node
{
    constructor(data)
    {
        this.data = data;
        this.left = null;
        this.right = null;
          
        // New Node which is created is
        // always red in color.
        this.color = true;
    }
}
 
let root = null;
 
// utility function to rotate node anticlockwise.
function rotateLeft(myNode)
{
    document.write("left rotation!!<br>");
        let child = myNode.right;
        let childLeft = child.left;
  
        child.left = myNode;
        myNode.right = childLeft;
  
        return child;
}
 
// utility function to rotate node clockwise.
function rotateRight(myNode)
{
    document.write("right rotation<br>");
        let child = myNode.left;
        let childRight = child.right;
  
        child.right = myNode;
        myNode.left = childRight;
  
        return child;
}
 
// utility function to check whether
    // node is red in color or not.
function isRed(myNode)
{
    if (myNode == null)
    return false;
    return (myNode.color == true);
}   
 
// utility function to swap color of two
    // nodes.
function swapColors(node1,node2)
{
    let temp = node1.color;
        node1.color = node2.color;
        node2.color = temp;
}
 
// insertion into Left Leaning Red Black Tree.
function insert(myNode,data)
{
    // Normal insertion code for any Binary
        // Search tree.
        if (myNode == null)
            return new node(data);
  
        if (data < myNode.data)
            myNode.left = insert(myNode.left, data);
          
        else if (data > myNode.data)
            myNode.right = insert(myNode.right, data);
          
        else
            return myNode;
  
  
        // case 1.
        // when right child is Red but left child is
        // Black or doesn't exist.
        if (isRed(myNode.right) && !isRed(myNode.left))
        {
            // left rotate the node to make it into
            // valid structure.
            myNode = rotateLeft(myNode);
  
            // swap the colors as the child node
            // should always be red
            swapColors(myNode, myNode.left);
  
        }
  
        // case 2
        // when left child as well as left grand child in Red
        if (isRed(myNode.left) && isRed(myNode.left.left))
        {
            // right rotate the current node to make
            // it into a valid structure.
            myNode = rotateRight(myNode);
            swapColors(myNode, myNode.right);
        }
  
  
        // case 3
        // when both left and right child are Red in color.
        if (isRed(myNode.left) && isRed(myNode.right))
        {
            // invert the color of node as well
            // it's left and right child.
            myNode.color = !myNode.color;
  
            // change the color to black.
            myNode.left.color = false;
            myNode.right.color = false;
        }
  
        return myNode;
}
 
// Inorder traversal
function inorder(node)
{
    if (node != null)
        {
            inorder(node.left);
            document.write(node.data + " ");
            inorder(node.right);
        }
}
 
/* LLRB tree made after all insertions are made.
 
    1. Nodes which have double INCOMING edge means
        that they are RED in color.
    2. Nodes which have single INCOMING edge means
        that they are BLACK in color.
 
        root
        |
        40
        // \
    20 50
    / \
    10 30
        //
        25 */
 
 
 
root = insert(root, 10);
// to make sure that root remains
// black is color
root.color = false;
 
root = insert(root, 20);
root.color = false;
 
root = insert(root, 30);
root.color = false;
 
root = insert(root, 40);
root.color = false;
 
root = insert(root, 50);
root.color = false;
 
root = insert(root, 25);
root.color = false;
 
// display the tree through inorder traversal.
inorder(root);
 
// This code is contributed by avanitrachhadiya2155
</script>

Output: 

left rotation!!
left rotation!!
left rotation!!
10 20 25 30 40 50 

Time Complexity: O(log n)
References 
Left Leaning Red Black Trees 
This article is contributed by Arshpreet Soodan. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :