Articles by FavTutor
  • AI News
  • Data Structures
  • Web Developement
  • AI Code GeneratorNEW
  • Student Help
  • Main Website
No Result
View All Result
FavTutor
  • AI News
  • Data Structures
  • Web Developement
  • AI Code GeneratorNEW
  • Student Help
  • Main Website
No Result
View All Result
Articles by FavTutor
No Result
View All Result
Home Data Structures and Algorithms

Check for Balanced Binary Tree (C++, Java, Python)

Jatin Chanana by Jatin Chanana
December 28, 2023
Reading Time: 9 mins read
Balanced Binary Tree Problem
Follow us on Google News   Subscribe to our newsletter

A balanced binary tree is an important data structure in optimizing search, insert, and delete operations. In this article, we will explore the concept of balanced binary trees, two different approaches to determining whether a given binary tree is height-balanced or not, and how to implement the solution.

What is the Balanced Binary Tree Problem?

In the Balanced Binary Tree problem, we are given a binary tree and we have to check whether the given binary tree is balanced or not. A binary tree is balanced when the depth of every node’s left and right subtrees differs by at most one.

Check the example of a balanced binary tree below: 

Balanced Binary Tree

As we can see the difference in heights for every subtree is not more than 1, it is balanced.

In the simplest naive approach, we will check the height of the left and right subtree for every node present in the tree for this we will traverse the tree recursively to calculate the height of the left and right subtree from every node, and whenever the condition of balanced binary tree violates, we will return false.

Naive Approach to check for balanced binary tree
  • We will start traversing the tree from Node 3: left height = 1 and right height = 2 absolute difference is (2-1) = 1
  • Node 6: left height = 0 and right height = 0 absolute difference is (0-0) = 0
  • PostOrder of Node 6, the left subtree (null) gives true & right subtree (null) gives true, as both are true, return true.
  • Node 7: left height = 1 and right height = 1 absolute difference is (1-1) = 0
  • Node 1: left height = 0 and right height = 0 absolute difference is (0-0) = 0
  • PostOrder of Node 1, the left subtree (null) gives true & right subtree (null) gives true, as both are true, return true.
  • Node 0: left height = 0 and right height = 0 absolute difference is (0-0) = 0.
  • PostOrder of Node 0, the left subtree (null) gives true & right subtree (null) gives true, as both are true, return true.
  • PostOrder of Node 7, the left subtree (1) gives true & right subtree (0) gives true, as both are true, return true.
  • PostOrder of Node 3, the left subtree (6) gives true & right subtree (7) gives true, as both are true, return true.

Overall all nodes are returning true which means our binary tree is a balanced binary tree. You can learn how to find the height of a binary tree using recursion as well.

The time complexity for this naive approach is O(N*N) because for every node height function is called which takes O(N) time hence every node is visited multiple times. The space complexity for this approach is O(1) (extra space) + O(H) recursive stack space where H is the height of the tree.

Post-order Traversal to Check Binary Tree is Balanced or Not

In the post-order traversal approach to check for a balanced binary tree, we will use the post-order traversal to recursively traverse the left subtree and the right subtree.

From this, we will calculate the height of the current node as the maximum height of its left and right subtrees, plus 1. Check if the current node is balanced by comparing the heights of its left and right subtrees. The tree is not balanced if the absolute difference is greater than 1.

Here is the step-by-step guide to doing it practically:

  1. First, we will declare the base case of our recursive function that if the current node equals NULL, it means we have reached the end of a branch. In this case, the height of this subtree is 0.
  2. Now we will start traversing the tree recursively with post-order calculating the height of the root node and returning to its previous call.
  3. While obtaining each node’s post order, we will check the condition of the balance tree as we have the height of the left and right subtree.
  4. If the tree is balanced we will simply return the height of the subtree otherwise we will return -1.
  5. If subtree is not balanced we will simply return -1.

Let’s see an example of the same:

Post-order Traversal to check for balanced binary tree
  • First of all, we reached the leftmost node, Node 6: Left child = null so Left Height = 0, Right child = null so Right Height = 0, Difference is 0-0 = 0, ( 0 <= 1 ) so return height, i.e. Max(0,0) + 1 = 1. 
  • Node 1: Left child = null so Left Height = 0, Right child = null so Right Height = 0, Difference is 0-0 = 0 , ( 0 <= 1 ) so return height , i.e. Max(0,0) + 1 = 1. 
  • Node 0: Left child = null so Left Height = 0, Right child = null so Right Height = 0 , Difference is 0-0 = 0 , ( 0 <= 1 ) so return height , i.e. Max(0,0) + 1 = 1. 
  • Node 7: Left child = 1 so Left Height = 1, Right child = 0 so Right Height = 1, Difference is 1-1= 0 , ( 0 <= 1 ) so return height , i.e. Max(1,1) + 1 = 2. 
  • Node 3: Left child = 6 so Left Height = 1, Right child = 7 so Right Height = 2, Difference is 2-1= 1 , ( 1 <= 1 ) so return height , i.e. Max(2,1) + 1 = 3 . 

Now we know how to do it, let’s implement it in various programming languages.

C++ Code

Below is the C++ program to check for balanced binary tree using post-order traversal:

#include<bits/stdc++.h>

using namespace std;

// Definition for a binary tree node.
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
public:
    // Function to check if the tree is balanced
    bool isBalanced(TreeNode* root) {
        // Call the helper function for DFS with post-order traversal
        return dfsHeight(root) != -1;
    }

    // Helper function for DFS with post-order traversal to calculate tree height
    int dfsHeight(TreeNode* root) {
        // Base case: if the current node is NULL, return 0
        if (root == NULL) return 0;

        // Recursively calculate the height of the left subtree
        int leftHeight = dfsHeight(root->left);
        // If the left subtree is unbalanced, propagate -1 up the recursion
        if (leftHeight == -1) 
            return -1;

        // Recursively calculate the height of the right subtree
        int rightHeight = dfsHeight(root->right);
        // If the right subtree is unbalanced, propagate -1 up the recursion
        if (rightHeight == -1) 
            return -1;

        // Check if the current subtree is balanced
        if (abs(leftHeight - rightHeight) > 1)  
            return -1;

        // Return the height of the current subtree
        return max(leftHeight, rightHeight) + 1;
    }
};

int main() {
    // Constructing the tree
    TreeNode* root = new TreeNode(3);
    root->left = new TreeNode(6);
    root->right = new TreeNode(7);
    root->right->left = new TreeNode(1);
    root->right->right = new TreeNode(0);

    // Creating an instance of the Solution class
    Solution solution;

    // Checking if the tree is balanced
    bool balanced = solution.isBalanced(root);

    // Output the result
    if (balanced) {
        cout << "The tree is balanced." << endl;
    } else {
        cout << "The tree is not balanced." << endl;
    }

    // Deallocating the memory
    // In a complete program, you would want to free the allocated memory for the tree nodes
    return 0;
}

Python Code

Here is the Python program to check for a balanced binary tree:

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def isBalanced(self, root):
        # Call the helper function for DFS with post-order traversal
        return self.dfs_height(root) != -1

    def dfs_height(self, root):
        # Base case: if the current node is None, return 0
        if root is None:
            return 0

        # Recursively calculate the height of the left subtree
        left_height = self.dfs_height(root.left)
        # If the left subtree is unbalanced, propagate -1 up the recursion
        if left_height == -1:
            return -1

        # Recursively calculate the height of the right subtree
        right_height = self.dfs_height(root.right)
        # If the right subtree is unbalanced, propagate -1 up the recursion
        if right_height == -1:
            return -1

        # Check if the current subtree is balanced
        if abs(left_height - right_height) > 1:
            return -1

        # Return the height of the current subtree
        return max(left_height, right_height) + 1

# Constructing the tree
root = TreeNode(3)
root.left = TreeNode(6)
root.right = TreeNode(7)
root.right.left = TreeNode(1)
root.right.right = TreeNode(0)

# Creating an instance of the Solution class
solution = Solution()

# Checking if the tree is balanced
balanced = solution.isBalanced(root)

# Output the result
if balanced:
    print("The tree is balanced.")
else:
    print("The tree is not balanced.")

Java Code

You can implement it in Java also:

// Definition for a binary tree node.
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

class Solution {
    // Function to check if the tree is balanced
    public boolean isBalanced(TreeNode root) {
        // Call the helper function for DFS with post-order traversal
        return dfsHeight(root) != -1;
    }

    // Helper function for DFS with post-order traversal to calculate tree height
    private int dfsHeight(TreeNode root) {
        // Base case: if the current node is null, return 0
        if (root == null)
            return 0;

        // Recursively calculate the height of the left subtree
        int leftHeight = dfsHeight(root.left);
        // If the left subtree is unbalanced, propagate -1 up the recursion
        if (leftHeight == -1)
            return -1;

        // Recursively calculate the height of the right subtree
        int rightHeight = dfsHeight(root.right);
        // If the right subtree is unbalanced, propagate -1 up the recursion
        if (rightHeight == -1)
            return -1;

        // Check if the current subtree is balanced
        if (Math.abs(leftHeight - rightHeight) > 1)
            return -1;

        // Return the height of the current subtree
        return Math.max(leftHeight, rightHeight) + 1;
    }
}

class Main {
    public static void main(String[] args) {
        // Constructing the tree
        TreeNode root = new TreeNode(3);
        root.left = new TreeNode(6);
        root.right = new TreeNode(7);
        root.right.left = new TreeNode(1);
        root.right.right = new TreeNode(0);

        // Creating an instance of the Solution class
        Solution solution = new Solution();

        // Checking if the tree is balanced
        boolean balanced = solution.isBalanced(root);

        // Output the result
        if (balanced) {
            System.out.println("The tree is balanced.");
        } else {
            System.out.println("The tree is not balanced.");
        }

        // In a complete program, you would want to free the allocated memory for the tree nodes
    }
}

The time complexity of the post-order traversal approach to check whether a binary tree is balanced or not is O(N), where N is the number of nodes in the binary tree. This is because each node is visited exactly once in a post-order traversal, and at each node, constant-time operations are performed.

The Space Complexity of this approach is O(1) Extra Space + O(H) Recursion Stack space (H is the height of the binary tree).

Before ending this article, let’s compare both the approaches:

ApproachTime complexitySpace complexityDetails
Brute force approachO(N*N)O(1) Each node is visited multiple times to find the height of the left and right subtree for each node
Optimized approachO(N)O(1) Each node is visited exactly once in a post-order traversal, and at each node, constant-time operations are performed.

By the way, there are many types of tree traversal available in programming.

Conclusion

In this article, we have discussed two approaches for checking for a balanced binary tree, which is very popular in leetcode as well. We have used the optimized approach using post-order traversal to solve this problem and implemented its code in C++, Java, and Python.

ShareTweetShareSendSend
Jatin Chanana

Jatin Chanana

I am Jatin, a final-year undergraduate student with a keen interest in the field of software development. I possess a strong academic background and a deep passion for Data Structures, Algorithms, and Web Development.

RelatedPosts

validate ip address

Validate IP Address Problem ( C++, JAVA, Python)

April 3, 2025
Shortest Palindrome Problem

Shortest Palindrome Problem ( C++, JAVA, Python)

April 4, 2025
Zigzag Conversion Problem

Zigzag Conversion Problem (C++, Java, Python)

April 4, 2025
Next Right Pointers In Each Node

Populating Next Right Pointers In Each Node (with code)

March 27, 2024
Coin Change II

Coin Change II Problem (C++, Java, Python)

April 7, 2025

About FavTutor

FavTutor is a trusted online tutoring service to connects students with expert tutors to provide guidance on Computer Science subjects like Java, Python, C, C++, SQL, Data Science, Statistics, etc.

Categories

  • AI News, Research & Latest Updates
  • Trending
  • Data Structures
  • Web Developement
  • Data Science

Important Subjects

  • Python Assignment Help
  • C++ Help
  • R Programming Help
  • Java Homework Help
  • Programming Help

Resources

  • About Us
  • Contact Us
  • Editorial Policy
  • Privacy Policy
  • Terms and Conditions

Website listed on Ecomswap. © Copyright 2025 All Rights Reserved.

No Result
View All Result
  • AI News
  • Data Structures
  • Web Developement
  • AI Code Generator
  • Student Help
  • Main Website

Website listed on Ecomswap. © Copyright 2025 All Rights Reserved.