Balance a Binary Search Tree
Last Updated :
05 Feb, 2025
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:
Output:
Explanation: The above unbalanced BST is converted to balanced with the minimum possible height.
Input:
Output:
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
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.
Similar Reads
Binary Search Tree A Binary Search Tree (BST) is a type of binary tree data structure in which each node contains a unique key and satisfies a specific ordering property:All nodes in the left subtree of a node contain values strictly less than the nodeâs value. All nodes in the right subtree of a node contain values s
4 min read
Introduction to Binary Search Tree Binary Search Tree is a data structure used in computer science for organizing and storing data in a sorted manner. Binary search tree follows all properties of binary tree and for every nodes, its left subtree contains values less than the node and the right subtree contains values greater than the
3 min read
Applications of BST Binary Search Tree (BST) is a data structure that is commonly used to implement efficient searching, insertion, and deletion operations along with maintaining sorted sequence of data. Please remember the following properties of BSTs before moving forward.The left subtree of a node contains only node
3 min read
Applications, Advantages and Disadvantages of Binary Search Tree A Binary Search Tree (BST) is a data structure used to storing data in a sorted manner. Each node in a Binary Search Tree has at most two children, a left child and a right child, with the left child containing values less than the parent node and the right child containing values greater than the p
2 min read
Insertion in Binary Search Tree (BST) Given a BST, the task is to insert a new node in this BST.Example: How to Insert a value in a Binary Search Tree:A new key is always inserted at the leaf by maintaining the property of the binary search tree. We start searching for a key from the root until we hit a leaf node. Once a leaf node is fo
15 min read
Searching in Binary Search Tree (BST) Given a BST, the task is to search a node in this BST. For searching a value in BST, consider it as a sorted array. Now we can easily perform search operation in BST using Binary Search Algorithm. Input: Root of the below BST Output: TrueExplanation: 8 is present in the BST as right child of rootInp
7 min read
Deletion in Binary Search Tree (BST) Given a BST, the task is to delete a node in this BST, which can be broken down into 3 scenarios:Case 1. Delete a Leaf Node in BST Case 2. Delete a Node with Single Child in BSTDeleting a single child node is also simple in BST. Copy the child to the node and delete the node. Case 3. Delete a Node w
10 min read
Binary Search Tree (BST) Traversals â Inorder, Preorder, Post Order Given a Binary Search Tree, The task is to print the elements in inorder, preorder, and postorder traversal of the Binary Search Tree. Input: A Binary Search TreeOutput: Inorder Traversal: 10 20 30 100 150 200 300Preorder Traversal: 100 20 10 30 200 150 300Postorder Traversal: 10 30 20 150 300 200 1
10 min read
Balance a Binary Search Tree 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: Output: Explanation: The above unbalanced BST is converted to balanced with the minimum possible height.Input: Output: Explanation: The above u
10 min read
Self-Balancing Binary Search Trees Self-Balancing Binary Search Trees are height-balanced binary search trees that automatically keep the height as small as possible when insertion and deletion operations are performed on the tree. The height is typically maintained in order of logN so that all operations take O(logN) time on average
4 min read