Check if a given Binary Tree is height balanced like a Red-Black Tree
Last Updated :
10 Jul, 2022
In a Red-Black Tree, the maximum height of a node is at most twice the minimum height (The four Red-Black tree properties make sure this is always followed). Given a Binary Search Tree, we need to check for following property.
For every node, length of the longest leaf to node path has not more than twice the nodes on shortest path from node to leaf.
12 40
\ / \
14 10 100
\ / \
16 60 150
Cannot be a Red-Black Tree It can be Red-Black Tree
with any color assignment
Max height of 12 is 1
Min height of 12 is 3
10
/ \
5 100
/ \
50 150
/
40
It can also be Red-Black Tree
Expected time complexity is O(n). The tree should be traversed at-most once in the solution.
We strongly recommend to minimize the browser and try this yourself first.
For every node, we need to get the maximum and minimum heights and compare them. The idea is to traverse the tree and for every node check if it's balanced. We need to write a recursive function that returns three things, a boolean value to indicate the tree is balanced or not, minimum height and maximum height. To return multiple values, we can either use a structure or pass variables by reference. We have passed maxh and minh by reference so that the values can be used in parent calls.
Implementation:
C++
/* Program to check if a given Binary Tree is balanced like a Red-Black Tree */
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int key;
Node *left, *right;
};
/* utility that allocates a new Node with the given key */
Node* newNode(int key)
{
Node* node = new Node;
node->key = key;
node->left = node->right = NULL;
return (node);
}
// Returns returns tree if the Binary tree is balanced like a Red-Black
// tree. This function also sets value in maxh and minh (passed by
// reference). maxh and minh are set as maximum and minimum heights of root.
bool isBalancedUtil(Node *root, int &maxh, int &minh)
{
// Base case
if (root == NULL)
{
maxh = minh = 0;
return true;
}
int lmxh, lmnh; // To store max and min heights of left subtree
int rmxh, rmnh; // To store max and min heights of right subtree
// Check if left subtree is balanced, also set lmxh and lmnh
if (isBalancedUtil(root->left, lmxh, lmnh) == false)
return false;
// Check if right subtree is balanced, also set rmxh and rmnh
if (isBalancedUtil(root->right, rmxh, rmnh) == false)
return false;
// Set the max and min heights of this node for the parent call
maxh = max(lmxh, rmxh) + 1;
minh = min(lmnh, rmnh) + 1;
// See if this node is balanced
if (maxh <= 2*minh)
return true;
return false;
}
// A wrapper over isBalancedUtil()
bool isBalanced(Node *root)
{
int maxh, minh;
return isBalancedUtil(root, maxh, minh);
}
/* Driver program to test above functions*/
int main()
{
Node * root = newNode(10);
root->left = newNode(5);
root->right = newNode(100);
root->right->left = newNode(50);
root->right->right = newNode(150);
root->right->left->left = newNode(40);
isBalanced(root)? cout << "Balanced" : cout << "Not Balanced";
return 0;
}
Java
// Java Program to check if a given Binary
// Tree is balanced like a Red-Black Tree
class GFG
{
static class Node
{
int key;
Node left, right;
Node(int key)
{
left = null;
right = null;
this.key = key;
}
}
static class INT
{
static int d;
INT()
{
d = 0;
}
}
// Returns returns tree if the Binary
// tree is balanced like a Red-Black
// tree. This function also sets value
// in maxh and minh (passed by reference).
// maxh and minh are set as maximum and
// minimum heights of root.
static boolean isBalancedUtil(Node root,
INT maxh, INT minh)
{
// Base case
if (root == null)
{
maxh.d = minh.d = 0;
return true;
}
// To store max and min heights of left subtree
INT lmxh=new INT(), lmnh=new INT();
// To store max and min heights of right subtree
INT rmxh=new INT(), rmnh=new INT();
// Check if left subtree is balanced,
// also set lmxh and lmnh
if (isBalancedUtil(root.left, lmxh, lmnh) == false)
return false;
// Check if right subtree is balanced,
// also set rmxh and rmnh
if (isBalancedUtil(root.right, rmxh, rmnh) == false)
return false;
// Set the max and min heights
// of this node for the parent call
maxh.d = Math.max(lmxh.d, rmxh.d) + 1;
minh.d = Math.min(lmnh.d, rmnh.d) + 1;
// See if this node is balanced
if (maxh.d <= 2*minh.d)
return true;
return false;
}
// A wrapper over isBalancedUtil()
static boolean isBalanced(Node root)
{
INT maxh=new INT(), minh=new INT();
return isBalancedUtil(root, maxh, minh);
}
// Driver code
public static void main(String args[])
{
Node root = new Node(10);
root.left = new Node(5);
root.right = new Node(100);
root.right.left = new Node(50);
root.right.right = new Node(150);
root.right.left.left = new Node(40);
System.out.println(isBalanced(root) ?
"Balanced" : "Not Balanced");
}
}
// This code is contributed by Arnab Kundu
Python3
""" Program to check if a given Binary
Tree is balanced like a Red-Black Tree """
# Helper function that allocates a new
# node with the given data and None
# left and right pointers.
class newNode:
# Construct to create a new node
def __init__(self, key):
self.data = key
self.left = None
self.right = None
# Returns returns tree if the Binary
# tree is balanced like a Red-Black
# tree. This function also sets value
# in maxh and minh (passed by
# reference). maxh and minh are set
# as maximum and minimum heights of root.
def isBalancedUtil(root, maxh, minh) :
# Base case
if (root == None) :
maxh = minh = 0
return True
lmxh=0
# To store max and min
# heights of left subtree
lmnh=0
# To store max and min
# heights of right subtree
rmxh, rmnh=0,0
# Check if left subtree is balanced,
# also set lmxh and lmnh
if (isBalancedUtil(root.left, lmxh, lmnh) == False) :
return False
# Check if right subtree is balanced,
# also set rmxh and rmnh
if (isBalancedUtil(root.right, rmxh, rmnh) == False) :
return False
# Set the max and min heights of
# this node for the parent call
maxh = max(lmxh, rmxh) + 1
minh = min(lmnh, rmnh) + 1
# See if this node is balanced
if (maxh <= 2 * minh) :
return True
return False
# A wrapper over isBalancedUtil()
def isBalanced(root) :
maxh, minh =0,0
return isBalancedUtil(root, maxh, minh)
# Driver Code
if __name__ == '__main__':
root = newNode(10)
root.left = newNode(5)
root.right = newNode(100)
root.right.left = newNode(50)
root.right.right = newNode(150)
root.right.left.left = newNode(40)
if (isBalanced(root)):
print("Balanced")
else:
print("Not Balanced")
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)
C#
// C# Program to check if a given Binary
// Tree is balanced like a Red-Black Tree
using System;
class GFG
{
public class Node
{
public int key;
public Node left, right;
public Node(int key)
{
left = null;
right = null;
this.key = key;
}
}
public class INT
{
public int d;
public INT()
{
d = 0;
}
}
// Returns returns tree if the Binary
// tree is balanced like a Red-Black
// tree. This function also sets value
// in maxh and minh (passed by reference).
// maxh and minh are set as maximum and
// minimum heights of root.
static bool isBalancedUtil(Node root,
INT maxh, INT minh)
{
// Base case
if (root == null)
{
maxh.d = minh.d = 0;
return true;
}
// To store max and min heights of left subtree
INT lmxh = new INT(), lmnh = new INT();
// To store max and min heights of right subtree
INT rmxh = new INT(), rmnh = new INT();
// Check if left subtree is balanced,
// also set lmxh and lmnh
if (isBalancedUtil(root.left, lmxh, lmnh) == false)
return false;
// Check if right subtree is balanced,
// also set rmxh and rmnh
if (isBalancedUtil(root.right, rmxh, rmnh) == false)
return false;
// Set the max and min heights
// of this node for the parent call
maxh.d = Math.Max(lmxh.d, rmxh.d) + 1;
minh.d = Math.Min(lmnh.d, rmnh.d) + 1;
// See if this node is balanced
if (maxh.d <= 2 * minh.d)
return true;
return false;
}
// A wrapper over isBalancedUtil()
static bool isBalanced(Node root)
{
INT maxh = new INT(), minh = new INT();
return isBalancedUtil(root, maxh, minh);
}
// Driver code
public static void Main(String []args)
{
Node root = new Node(10);
root.left = new Node(5);
root.right = new Node(100);
root.right.left = new Node(50);
root.right.right = new Node(150);
root.right.left.left = new Node(40);
Console.WriteLine(isBalanced(root) ?
"Balanced" : "Not Balanced");
}
}
// This code contributed by Rajput-Ji
JavaScript
<script>
// JavaScript Program to check if a given Binary
// Tree is balanced like a Red-Black Tree
class Node {
constructor(val) {
this.key = val;
this.left = null;
this.right = null;
}
}
class INT {
constructor() {
this.d = 0;
}
}
// Returns returns tree if the Binary
// tree is balanced like a Red-Black
// tree. This function also sets value
// in maxh and minh (passed by reference).
// maxh and minh are set as maximum and
// minimum heights of root.
function isBalancedUtil(root, maxh, minh) {
// Base case
if (root == null) {
maxh.d = minh.d = 0;
return true;
}
// To store max and min heights of left subtree
var lmxh = new INT(), lmnh = new INT();
// To store max and min heights of right subtree
var rmxh = new INT(), rmnh = new INT();
// Check if left subtree is balanced,
// also set lmxh and lmnh
if (isBalancedUtil(root.left, lmxh, lmnh) == false)
return false;
// Check if right subtree is balanced,
// also set rmxh and rmnh
if (isBalancedUtil(root.right, rmxh, rmnh) == false)
return false;
// Set the max and min heights
// of this node for the parent call
maxh.d = Math.max(lmxh.d, rmxh.d) + 1;
minh.d = Math.min(lmnh.d, rmnh.d) + 1;
// See if this node is balanced
if (maxh.d <= 2 * minh.d)
return true;
return false;
}
// A wrapper over isBalancedUtil()
function isBalanced(root) {
var maxh = new INT(), minh = new INT();
return isBalancedUtil(root, maxh, minh);
}
// Driver code
var root = new Node(10);
root.left = new Node(5);
root.right = new Node(100);
root.right.left = new Node(50);
root.right.right = new Node(150);
root.right.left.left = new Node(40);
document.write(isBalanced(root) ?
"Balanced" : "Not Balanced");
// This code contributed by umadevi9616
</script>
Time Complexity: Time Complexity of above code is O(n) as the code does a simple tree traversal.
Auxiliary Space: O(n) for call stack since using recursion
Similar Reads
Introduction to Red-Black Tree Binary search trees are a fundamental data structure, but their performance can suffer if the tree becomes unbalanced. Red Black Trees are a type of balanced binary search tree that use a set of rules to maintain balance, ensuring logarithmic time complexity for operations like insertion, deletion,
15 min read
Red-Black Tree definition & meaning in DSA A red-black tree is a self-balancing binary search tree in which each node of the tree has an color, which can either be red or black. Example of Red-Black TreeCharacteristics of Red Black Tree:The root node is always black and each node can be either black or red.Every leaf node of the red-black tr
2 min read
Applications, Advantages and Disadvantages of Red-Black Tree Red-Black Tree is one type of self-balancing tree where each node has one extra bit that is often interpreted as colour of the node. This bit (the colour) is used to ensure that the tree remains balanced. Properties of Red-Black Trees: Red-Black Trees have the accompanying properties: Each hub has a
4 min read
Insertion in Red-Black Tree In the previous post, we discussed the introduction to Red-Black Trees. In this post, insertion is discussed. In AVL tree insertion, we used rotation as a tool to do balancing after insertion. In the Red-Black tree, we use two tools to do the balancing. RecoloringRotationRecolouring is the change in
15+ min read
C Program for Red Black Tree Insertion Following article is extension of article discussed here.In AVL tree insertion, we used rotation as a tool to do balancing after insertion caused imbalance. In Red-Black tree, we use two tools to do balancing. Recoloring Rotation We try recoloring first, if recoloring doesn't work, then we go for ro
6 min read
Deletion in Red-Black Tree Deletion in a red-black tree is a bit more complicated than insertion. When a node is to be deleted, it can either have no children, one child or two children. Here are the steps involved in deleting a node in a red-black tree:If the node to be deleted has no children, simply remove it and update th
15+ min read
Red-Black Trees | Top-Down Insertion In Bottom-Up insertion of Red-Black Trees, "simple" Binary Search Tree insertion is used, followed by correction of the RB-Tree Violations on the way back up to the root. This can be done easily with the help of recursion. While in Top-Down Insertion, the corrections are done while traversing down t
15+ min read
Left Leaning Red Black Tree (Insertion) Prerequisites : Red - Black Trees.A left leaning Red Black Tree or (LLRB), is a variant of red black tree, which is a lot easier to implement than Red black tree itself and guarantees all the search, delete and insert operations in O(logn) time. Which nodes are RED and Which are Black ? Nodes which
15+ min read
Check if a given Binary Tree is height balanced like a Red-Black Tree In a Red-Black Tree, the maximum height of a node is at most twice the minimum height (The four Red-Black tree properties make sure this is always followed). Given a Binary Search Tree, we need to check for following property. For every node, length of the longest leaf to node path has not more than
9 min read
What is the difference between Heap and Red-Black Tree? What is Heap? A Heap is a special Tree-based data structure in which the tree is a complete binary tree. There are two types of heap - Min heap and Max heap. To learn more about heap, go through the following article: Introduction to Heap What is a Red-Black Tree?The red-Black tree is a self-balanci
2 min read