Open In App

Balance a Binary Search Tree

Last Updated : 05 Feb, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a BST (Binary Search Tree) that may be unbalanced, the task is to convert it into a balanced BST that has the minimum possible height.

Examples: 

Input:

Balance-a-Binary-Search-Tree

Output:

Balance-a-Binary-Search-Tree-3


Explanation: The above unbalanced BST is converted to balanced with the minimum possible height.

Input:

Balance-a-Binary-Search-Tree-2


Output:

Balance-a-Binary-Search-Tree-4

Explanation: The above unbalanced BST is converted to balanced with the minimum possible height.

Approach:

The idea is to store the elements of the tree in an array using inorder traversal. Inorder traversal of a BST produces a sorted array. Once we have a sorted array, recursively construct a balanced BST by picking the middle element of the array as the root for each subtree.

Follow the steps below to solve the problem:

  • Traverse given BST in inorder and store result in an array. Note that this array would be sorted as inorder traversal of BST always produces sorted sequence.
  • Build a balanced BST from the above created sorted array using the recursive approach discussed in Sorted Array to Balanced BST.
C++
//Driver Code Starts
// C++ program to convert a left unbalanced BST to
// a balanced BST

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

class Node {
public:
    int data;
    Node* left;
    Node* right;

    Node(int value) {
        data = value;
        left = nullptr;
        right = nullptr;
    }
};
//Driver Code Ends


// Inorder traversal to store elements of the
// tree in sorted order
void storeInorder(Node* root, vector<int>& nodes) {
    if (root == nullptr) 
        return;

    // Traverse the left subtree
    storeInorder(root->left, nodes);

    // Store the node data
    nodes.push_back(root->data);

    // Traverse the right subtree
    storeInorder(root->right, nodes);
}

// Function to build a balanced BST from a sorted array
Node* buildBalancedTree(vector<int>& nodes, int start, int end) {
    
    // Base case
    if (start > end) 
        return nullptr;

    // Get the middle element and make it the root
    int mid = (start + end) / 2;
    Node* root = new Node(nodes[mid]);

    // Recursively build the left and right subtrees
    root->left = buildBalancedTree(nodes, start, mid - 1);
    root->right = buildBalancedTree(nodes, mid + 1, end);

    return root;
}

// Function to balance a BST
Node* balanceBST(Node* root) {
    vector<int> nodes;

    // Store the nodes in sorted order
    storeInorder(root, nodes);

    // Build the balanced tree from the sorted nodes
    return buildBalancedTree(nodes, 0, nodes.size() - 1);
}


//Driver Code Starts
// Print tree as level order
void printLevelOrder(Node *root) {
    if (root == nullptr) {
        cout << "N ";
        return;
    }

    queue<Node *> qq;
    qq.push(root);
    int nonNull = 1;

    while (!qq.empty() && nonNull > 0) {
        Node *curr = qq.front();
        qq.pop();

        if (curr == nullptr) {
            cout << "N ";
            continue;
        }
        nonNull--;

        cout << (curr->data) << " ";
        qq.push(curr->left);
        qq.push(curr->right);
        if (curr->left)
            nonNull++;
        if (curr->right)
            nonNull++;
    }
}

int main() {
    
    // Constructing an unbalanced BST
    //        4
    //       / \
    //      3   5
    //     /     \
    //    2       6
    //   /		   \
    //  1		    7

    Node* root = new Node(4);
    root->left = new Node(3);
    root->left->left = new Node(2);
    root->left->left->left = new Node(1);
    root->right = new Node(5);
    root->right->right = new Node(6);
  	root->right->right->right = new Node(7);

    Node* balancedRoot = balanceBST(root);
    printLevelOrder(balancedRoot);

    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
// Java program to convert a left unbalanced BST to
// a balanced BST

import java.util.*;

class Node {
    int data;
    Node left, right;

    Node(int value) {
        data = value;
        left = null;
        right = null;
    }
}

class GFG {
//Driver Code Ends


    // Inorder traversal to store elements of the
    // tree in sorted order
    static void storeInorder(Node root, ArrayList<Integer> nodes) {
        if (root == null)
            return;

        // Traverse the left subtree
        storeInorder(root.left, nodes);

        // Store the node data
        nodes.add(root.data);

        // Traverse the right subtree
        storeInorder(root.right, nodes);
    }

    // Function to build a balanced BST from a sorted array
    static Node buildBalancedTree(ArrayList<Integer> nodes, int start, int end) {

        // Base case
        if (start > end)
            return null;

        // Get the middle element and make it the root
        int mid = (start + end) / 2;
        Node root = new Node(nodes.get(mid));

        // Recursively build the left and right subtrees
        root.left = buildBalancedTree(nodes, start, mid - 1);
        root.right = buildBalancedTree(nodes, mid + 1, end);

        return root;
    }

    // Function to balance a BST
    static Node balanceBST(Node root) {
        ArrayList<Integer> nodes = new ArrayList<>();

        // Store the nodes in sorted order
        storeInorder(root, nodes);

        // Build the balanced tree from the sorted nodes
        return buildBalancedTree(nodes, 0, nodes.size() - 1);
    }


//Driver Code Starts
    // Print tree as level order
    static void printLevelOrder(Node root) {
        if (root == null) {
            System.out.print("N ");
            return;
        }

        Queue<Node> qq = new LinkedList<>();
        qq.add(root);
        int nonNull = 1;

        while (!qq.isEmpty() && nonNull > 0) {
            Node curr = qq.poll();

            if (curr == null) {
                System.out.print("N ");
                continue;
            }
            nonNull--;

            System.out.print(curr.data + " ");
            qq.add(curr.left);
            qq.add(curr.right);
            if (curr.left != null)
                nonNull++;
            if (curr.right != null)
                nonNull++;
        }
    }

    public static void main(String[] args) {

        // Constructing an unbalanced BST
        //        4
        //       / \
        //      3   5
        //     /     \
        //    2       6
        //   /		   \
        //  1		    7

        Node root = new Node(4);
        root.left = new Node(3);
        root.left.left = new Node(2);
        root.left.left.left = new Node(1);
        root.right = new Node(5);
        root.right.right = new Node(6);
        root.right.right.right = new Node(7);

        Node balancedRoot = balanceBST(root);
        printLevelOrder(balancedRoot);
    }
}

//Driver Code Ends
Python
#Driver Code Starts
# Python program to convert a left unbalanced BST to
# a balanced BST

class Node:
    def __init__(self, value):
        self.data = value
        self.left = None
        self.right = None
#Driver Code Ends


# Inorder traversal to store elements of the
# tree in sorted order
def storeInorder(root, nodes):
    if root is None:
        return

    # Traverse the left subtree
    storeInorder(root.left, nodes)

    # Store the node data
    nodes.append(root.data)

    # Traverse the right subtree
    storeInorder(root.right, nodes)

# Function to build a balanced BST from a sorted array
def buildBalancedTree(nodes, start, end):
    # Base case
    if start > end:
        return None

    # Get the middle element and make it the root
    mid = (start + end) // 2
    root = Node(nodes[mid])

    # Recursively build the left and right subtrees
    root.left = buildBalancedTree(nodes, start, mid - 1)
    root.right = buildBalancedTree(nodes, mid + 1, end)

    return root

# Function to balance a BST
def balanceBST(root):
    nodes = []

    # Store the nodes in sorted order
    storeInorder(root, nodes)

    # Build the balanced tree from the sorted nodes
    return buildBalancedTree(nodes, 0, len(nodes) - 1)


#Driver Code Starts
# Print tree as level order
from collections import deque

def printLevelOrder(root):
    if root is None:
        print("N", end=" ")
        return

    queue = deque([root])
    nonNull = 1

    while queue and nonNull > 0:
        curr = queue.popleft()

        if curr is None:
            print("N", end=" ")
            continue
        nonNull -= 1

        print(curr.data, end=" ")
        queue.append(curr.left)
        queue.append(curr.right)
        if curr.left:
            nonNull += 1
        if curr.right:
            nonNull += 1

if __name__ == "__main__":
    root = Node(4)
    root.left = Node(3)
    root.left.left = Node(2)
    root.left.left.left = Node(1)
    root.right = Node(5)
    root.right.right = Node(6)
    root.right.right.right = Node(7)

    balancedRoot = balanceBST(root)
    printLevelOrder(balancedRoot)

#Driver Code Ends
C#
//Driver Code Starts
// C# program to convert a left unbalanced BST to
// a balanced BST

using System;
using System.Collections.Generic;

class Node {
    public int data;
    public Node left, right;

    public Node(int value) {
        data = value;
        left = null;
        right = null;
    }
}

class GFG {
//Driver Code Ends

  
    // Inorder traversal to store elements of the
    // tree in sorted order
    static void storeInorder(Node root, List<int> nodes) {
        if (root == null)
            return;

        // Traverse the left subtree
        storeInorder(root.left, nodes);

        // Store the node data
        nodes.Add(root.data);

        // Traverse the right subtree
        storeInorder(root.right, nodes);
    }

    // Function to build a balanced BST from a sorted array
    static Node buildBalancedTree(List<int> nodes, int start, int end) {
        // Base case
        if (start > end)
            return null;

        // Get the middle element and make it the root
        int mid = (start + end) / 2;
        Node root = new Node(nodes[mid]);

        // Recursively build the left and right subtrees
        root.left = buildBalancedTree(nodes, start, mid - 1);
        root.right = buildBalancedTree(nodes, mid + 1, end);

        return root;
    }

    // Function to balance a BST
    static Node balanceBST(Node root) {
        List<int> nodes = new List<int>();

        // Store the nodes in sorted order
        storeInorder(root, nodes);

        // Build the balanced tree from the sorted nodes
        return buildBalancedTree(nodes, 0, nodes.Count - 1);
    }


//Driver Code Starts
    // Print tree as level order
    static void printLevelOrder(Node root) {
        if (root == null) {
            Console.Write("N ");
            return;
        }

        Queue<Node> qq = new Queue<Node>();
        qq.Enqueue(root);
        int nonNull = 1;

        while (qq.Count > 0 && nonNull > 0) {
            Node curr = qq.Dequeue();

            if (curr == null) {
                Console.Write("N ");
                continue;
            }
            nonNull--;

            Console.Write(curr.data + " ");
            qq.Enqueue(curr.left);
            qq.Enqueue(curr.right);
            if (curr.left != null)
                nonNull++;
            if (curr.right != null)
                nonNull++;
        }
    }
  	
    static void Main() {
        
        // Constructing an unbalanced BST
        //        4
        //       / \
        //      3   5
        //     /     \
        //    2       6
        //   /        \
        //  1          7

        Node root = new Node(4);
        root.left = new Node(3);
        root.left.left = new Node(2);
        root.left.left.left = new Node(1);
        root.right = new Node(5);
        root.right.right = new Node(6);
        root.right.right.right = new Node(7);

        Node balancedRoot = balanceBST(root);
        printLevelOrder(balancedRoot);
    }
}

//Driver Code Ends
JavaScript
//Driver Code Starts
// JavaScript program to convert a left unbalanced BST to
// a balanced BST

class Node {
    constructor(value) {
        this.data = value;
        this.left = null;
        this.right = null;
    }
}
//Driver Code Ends


// Inorder traversal to store elements of the
// tree in sorted order
function storeInorder(root, nodes) {
    if (root === null)
        return;

    // Traverse the left subtree
    storeInorder(root.left, nodes);

    // Store the node data
    nodes.push(root.data);

    // Traverse the right subtree
    storeInorder(root.right, nodes);
}

// Function to build a balanced BST from a sorted array
function buildBalancedTree(nodes, start, end) {
    // Base case
    if (start > end)
        return null;

    // Get the middle element and make it the root
    let mid = Math.floor((start + end) / 2);
    let root = new Node(nodes[mid]);

    // Recursively build the left and right subtrees
    root.left = buildBalancedTree(nodes, start, mid - 1);
    root.right = buildBalancedTree(nodes, mid + 1, end);

    return root;
}

// Function to balance a BST
function balanceBST(root) {
    let nodes = [];

    // Store the nodes in sorted order
    storeInorder(root, nodes);

    // Build the balanced tree from the sorted nodes
    return buildBalancedTree(nodes, 0, nodes.length - 1);
}


//Driver Code Starts
// Print tree as level order
function printLevelOrder(root) {
    if (root === null) {
        console.log("N");
        return;
    }

    let queue = [];
    queue.push(root);
    let nonNull = 1;

    while (queue.length > 0 && nonNull > 0) {
        let curr = queue.shift();

        if (curr === null) {
            process.stdout.write("N ");
            continue;
        }
        nonNull--;

        process.stdout.write(curr.data + " ");
        queue.push(curr.left);
        queue.push(curr.right);
        if (curr.left)
            nonNull++;
        if (curr.right)
            nonNull++;
    }
}

// Driver Code
// Constructing an unbalanced BST
//        4
//       / \
//      3   5
//     /     \
//    2       6
//   /        \
//  1          7

let root = new Node(4);
root.left = new Node(3);
root.left.left = new Node(2);
root.left.left.left = new Node(1);
root.right = new Node(5);
root.right.right = new Node(6);
root.right.right.right = new Node(7);

let balancedRoot = balanceBST(root);
printLevelOrder(balancedRoot);

//Driver Code Ends

Output
4 2 6 1 3 5 7 

Time Complexity: O(n), as we are just traversing the tree twice. Once in inorder traversal and then in construction of the balanced tree.
Auxiliary space: O(n), as extra space is used to store the nodes of the inorder traversal in the vector. Also the extra space taken by recursion call stack is O(h) where h is the height of the tree.



Next Article
Article Tags :
Practice Tags :

Similar Reads