Golang program to perform a left rotation in a Red Black Tree


A red black tree is a self balancing binary search tree. Rotation is one of the fundamental operations of a self balancing tree. It is performed to maintain the tree's properties while inserting and deleting nodes to the tree. In this article we are going to write a language program to perform left rotation in a Red Black tree using pointers as well as using node value.

Properties of Red Black tree

  • Every node is either red or black

  • The root node is always black

  • Every leaf node is considered black

  • If a node is red, both its children are black

Algorithm

  • Step 1 − Import the main and fmt packages.

  • Step 2  − Check whether the input node and right child already exist or not. Exit the function if not.

  • Step 3 − Assign the right child of the node to the pivot variable.

  • Step 4 − Now update the node's right child to the pivot's left child.

  • Step 5 − If the left child of the pivot already exists, then update the parent of the left child of pivot to the node.

  • Step 6 − Now update the parent of pivot to the parent of node. If node is root, update root reference.

Example 1: Using pointers and swapping nodes

A leftRotation is the fundamental method of a red black tree that is used to balance the while maintaining the orders of the element. In this method we are going to use the left rotation by manipulating the pointers and swapping the node references.

package main

import (
   "fmt"
)

type Node struct {
   key    int
   color  bool
   left   *Node
   right  *Node
   parent *Node
}

var root *Node

func leftRotate(node *Node) {
   if node == nil || node.right == nil {
      return
   }

   pivot := node.right
   node.right = pivot.left

   if pivot.left != nil {
      pivot.left.parent = node
   }

   pivot.parent = node.parent

   if node.parent == nil {
      // If the node was the root, update the root reference
      root = pivot
   } else if node == node.parent.left {
      node.parent.left = pivot
   } else {
      node.parent.right = pivot
   }

   pivot.left = node
   node.parent = pivot
}

func main() {
   // Sample usage of leftRotate function
   root = &Node{
      key:   15,
      color: false,
      left:  nil,
      right: nil,
   }

   node1 := &Node{
      key:   25,
      color: true,
      left:  nil,
      right: nil,
   }

   node2 := &Node{
      key:   35,
      color: true,
      left:  nil,
      right: nil,
   }

   root.right = node1
   node1.parent = root
   node1.right = node2
   node2.parent = node1

   fmt.Println("Before left rotation:")
   fmt.Println("Rootkey:", root.key)
   fmt.Println("right child key of Root :", root.right.key)
   fmt.Println(" right child key of right child key of root:", root.right.right.key)

   leftRotate(root)

   fmt.Println("\nAfter left rotation:")
   fmt.Println("Rootkey:", root.key)
   fmt.Println("left child key of Root's :", root.left.key)
}

Output

Before left rotation: 
Rootkey: 15 
right child key of Root : 25
right child key of right child key of root: 35

After left rotation:
Rootkey: 25 
left child key of Root's : 15

Example 2: Using Node value

A leftRotation is the fundamental method of a red black tree that is used to balance the while maintaining the orders of the element. In this method we are going to use the left rotation by copying the values of nodes instead of directly manipulating the pointers.

package main

import (
   "fmt"
)

type Node struct {
   key    int
   color  bool
   left   *Node
   right  *Node
   parent *Node
}

var root *Node

func leftRotate(node *Node) {
   if node == nil || node.right == nil {
      return
   }

   pivot := &Node{
      key:    node.right.key,
      color:  node.right.color,
      left:   node.left,
      right:  node.right.left,
      parent: node,
   }

   if pivot.left != nil {
      pivot.left.parent = pivot
   }

   node.right = pivot
   if pivot.right != nil {
      pivot.right.parent = pivot
   }

   if node.parent == nil {
      root = pivot
   } else if node == node.parent.left {
      node.parent.left = pivot
   } else {
      node.parent.right = pivot
   }

   pivot.parent = node.parent
   node.parent = pivot
}

func main() {
   root = &Node{
      key:   15,
      color: false,
      left:  nil,
      right: nil,
   }

   node1 := &Node{
      key:   25,
      color: true,
      left:  nil,
      right: nil,
   }

   node2 := &Node{
      key:   35,
      color: true,
      left:  nil,
      right: nil,
   }

   root.right = node1
   node1.parent = root
   node1.right = node2
   node2.parent = node1

   fmt.Println("Before left rotation:")
   fmt.Println("Root key:", root.key)
   fmt.Println("Right child key of Root:", root.right.key)
   fmt.Println("Right child key of right child key of Root:", root.right.right.key)

   leftRotate(root)

   fmt.Println("\nAfter left rotation:")
   fmt.Println("Root key:", root.key)
}

Output

Before left rotation: 
Rootkey: 15 
right child key of Root : 25
right child key of right child key of root: 35

After left rotation:
Rootkey: 25 
left child key of Root's : 15

Conclusion

In this article we have checked how we can perform the left rotation on a red black tree in go-language.We explored how to perform this operation using pointers and swapping nodes as well as using the node value. Performing these operations on a self balancing tree like a red black tree is crucial to maintain its balance.

Updated on: 06-Jul-2023

45 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements