Open In App

AVL Tree Implementation in Golang

Improve
Improve
Like Article
Like
Save
Share
Report

An AVL tree is a type of self-balancing binary search tree that maintains the balance of the tree by ensuring that the difference between the heights of the left and right subtrees is at most one. This allows for efficient insertion, deletion, and search operations.

Approach:

We start by defining a node structure that will store the data, the left and right pointers to the children nodes, and the balance factor.

type Node struct {
key  int
left *Node
right *Node
height int
}

Steps Involved in Implementation:

  • Insertion: We start by inserting the node at the correct position in the tree. We then traverse up the tree and check the balance factor at each node. If the balance factor of any node is found to be greater than 1 or less than -1, then we need to perform a rotation to restore the balance of the tree.
  • Deletion: The deletion process is similar to insertion except that we need to check the balance factor at each node after the node is deleted. We also need to perform a rotation if the balance factor of any node is found to be greater than 1 or less than -1.
  • Search: The search process is similar to that of a regular binary search tree. We start at the root node and compare the data to be searched with the current node’s data. If the data is found, we return the node. If the data is less than the current node’s data, we move to the left child. If the data is greater than the current node’s data, we move to the right child. We keep repeating the process until the data is found or we reach a leaf node.

Below is the implementation of AVL Tree in Golang:

Go




// Golang Code
package main
  
import "fmt"
  
// Node structure to store the data and 
// the pointers to the left and 
// right children
type Node struct {
    key    int
    left   *Node
    right  *Node
    height int
}
  
// Function to find max of two integers
func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}
  
// Calculates the height of the node
func height(N *Node) int {
    if N == nil {
        return 0
    }
    return N.height
}
  
// Creates a new Node structure
func newNode(key int) *Node {
    node := &Node{key: key}
    node.left = nil
    node.right = nil
    node.height = 1
    return node
}
  
// Performs a right rotation on the node
func rightRotate(y *Node) *Node {
    x := y.left
    T2 := x.right
    x.right = y
    y.left = T2
    y.height = max(height(y.left), height(y.right)) + 1
    x.height = max(height(x.left), height(x.right)) + 1
    return x
}
  
// Performs a left rotation on the node
func leftRotate(x *Node) *Node {
    y := x.right
    T2 := y.left
    y.left = x
    x.right = T2
    x.height = max(height(x.left), height(x.right)) + 1
    y.height = max(height(y.left), height(y.right)) + 1
    return y
}
  
// Calculates the balance factor 
// of the node
func getBalanceFactor(N *Node) int {
    if N == nil {
        return 0
    }
    return height(N.left) - height(N.right)
}
  
// Inserts a new node into the 
// AVL Tree
func insertNode(node *Node, key int) *Node {
    if node == nil {
        return newNode(key)
    }
    if key < node.key {
        node.left = insertNode(node.left, key)
    } else if key > node.key {
        node.right = insertNode(node.right, key)
    } else {
        return node
    }
  
    node.height = 1 + max(height(node.left), height(node.right))
    balanceFactor := getBalanceFactor(node)
  
    if balanceFactor > 1 {
        if key < node.left.key {
            return rightRotate(node)
        } else if key > node.left.key {
            node.left = leftRotate(node.left)
            return rightRotate(node)
        }
    }
  
    if balanceFactor < -1 {
        if key > node.right.key {
            return leftRotate(node)
        } else if key < node.right.key {
            node.right = rightRotate(node.right)
            return leftRotate(node)
        }
    }
  
    return node
}
  
// Fetches the Node with minimum 
// value from the AVL tree
func nodeWithMinimumValue(node *Node) *Node {
    current := node
    for current.left != nil {
        current = current.left
    }
    return current
}
  
// Deletes a node from the AVL Tree
func deleteNode(root *Node, key int) *Node {
  
    // Searching Node
    if root == nil {
        return root
    }
    if key < root.key {
        root.left = deleteNode(root.left, key)
    } else if key > root.key {
        root.right = deleteNode(root.right, key)
    } else {
        if root.left == nil || root.right == nil {
            temp := root.left
            if temp == nil {
                temp = root.right
            }
            if temp == nil {
                temp = root
                root = nil
            } else {
                *root = *temp
            }
        } else {
            temp := nodeWithMinimumValue(root.right)
            root.key = temp.key
            root.right = deleteNode(root.right, temp.key)
        }
    }
    if root == nil {
        return root
    }
    root.height = 1 + max(height(root.left), height(root.right))
    balanceFactor := getBalanceFactor(root)
  
    if balanceFactor > 1 {
        if getBalanceFactor(root.left) >= 0 {
            return rightRotate(root)
        } else {
            root.left = leftRotate(root.left)
            return rightRotate(root)
        }
    }
    if balanceFactor < -1 {
        if getBalanceFactor(root.right) <= 0 {
            return leftRotate(root)
        } else {
            root.right = rightRotate(root.right)
            return leftRotate(root)
        }
    }
    return root
}
  
// Prints the AVL tree
func printTree(root *Node, indent string, last bool) {
    if root != nil {
        fmt.Print(indent)
        if last {
            fmt.Print("R----")
            indent += "   "
        } else {
            fmt.Print("L----")
            indent += "|  "
        }
        fmt.Println(root.key)
        printTree(root.left, indent, false)
        printTree(root.right, indent, true)
    }
}
  
func main() {
  
    // Creating AVL tree and 
    // inserting data in it
    root := insertNode(nil, 33)
    root = insertNode(root, 13)
    root = insertNode(root, 53)
    root = insertNode(root, 9)
    root = insertNode(root, 21)
    root = insertNode(root, 61)
    root = insertNode(root, 8)
    root = insertNode(root, 11)
  
    // Printing AVL Tree
    printTree(root, "", true)
  
    // Deleting a node from AVL Tree
    root = deleteNode(root, 13)
    fmt.Println("After deleting ")
    printTree(root, "", true)
}


Output:

R----33
   L----13
   |  L----9
   |  |  L----8
   |  |  R----11
   |  R----21
   R----53
      R----61
After deleting 
R----33
   L----9
   |  L----8
   |  R----21
   |     L----11
   R----53
      R----61

Time Complexity: O(log n)
Auxiliary Space: O(n)



Last Updated : 25 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads