Balanced Binary Tree in C++
Last Updated :
18 Jul, 2024
A Balanced Binary Tree, also known as a height-balanced binary tree, is a binary tree in which the height of every node's left and right subtrees differs by at most one. This balance condition ensures that the tree maintains a logarithmic height, which in turn guarantees O(log n) time complexity for operations such as insertion, deletion, and search.
In this article, we will learn how to implement a Balanced Binary Tree in C++ and its basic operations.
A Balanced Binary Tree is a binary tree where the heights of the left and right subtrees of any node differ by at most one. This balance condition is maintained through rotations during insertions and deletions.
Properties of Balanced Binary Trees
- The height difference between the left and right subtrees of any node is at most 1.
- Both the left and right subtrees are also balanced binary trees.
- The height of an empty tree is considered -1.
- The height of a tree with one node is 0.
Balanced vs Unbalanced Binary TreeImplementation of Balanced Binary Tree in C++ Language
A Balanced Binary Tree can be implemented using a self-balancing binary search tree, such as an AVL tree or a Red-Black tree. For this implementation, we'll use an AVL tree, which maintains balance by storing height information in each node and performing rotations when necessary.
Representation of Balanced Binary Tree in C++
To represent a balanced binary tree we will implement a class Node that will represent a single node of the balanced binary tree and BalancedBinaryTree class that will contain all the required member functions. We will use template to keep the balanced binary tree generic so that it can support multiple data types.
template <typename T>
class Node {
public:
T data;
Node* left;
Node* right;
int height;
};
Here,
- data: stores the value in the node.
- left and right: store pointers to the left and right child nodes.
- height: stores the height of the subtree rooted at this node.
The following diagram represents the structure of a balanced binary tree:
Balanced Binary TreeBasic Operations of Balanced Binary Tree in C++
Following are some of the basic operations of a Balanced Binary Tree that are required to manipulate its elements:
Operation | Description | Time Complexity | Space Complexity |
---|
Insert | Inserts a new element into the tree | O(log n) | O(1) |
---|
Delete | Removes an element from the tree | O(log n) | O(1) |
---|
Search | Searches for an element in the tree | O(log n) | O(1) |
---|
Height | Calculates the height of a node | O(1) | O(1) |
---|
Balance Factor | Calculates the balance factor of a node | O(1) | O(1) |
---|
Rotate Right | Performs a right rotation on a node | O(1) | O(1) |
---|
Rotate Left | Performs a left rotation on a node | O(1) | O(1) |
---|
Here, n represents the number of nodes in the tree.
Implementation of Insert Function
- Perform a standard BST insertion.
- Update the height of the ancestors nodes.
- Check the balance factor of the ancestors.
- If the node becomes unbalanced, perform one of the four rotations:
- Left-Left Case: Right Rotation
- Left-Right Case: Left Rotation followed by Right Rotation
- Right-Right Case: Left Rotation
- Right-Left Case: Right Rotation followed by Left Rotation
Implementation of Delete Function
- Perform a standard BST deletion.
- Update the height of the ancestors nodes.
- Check the balance factor of the ancestors.
- If the node becomes unbalanced, perform one of the four rotations as in insertion.
Implementation of Height and Balance Factor Functions
- Height: Return the height stored in the node, or 0 if the node is null.
- Balance Factor: Calculate the difference between the heights of left and right subtrees and return the calculated value.
Implementation of Rotation Functions
- Right Rotation:
- Make the left child of the current node the new root of the subtree.
- Make the old root the right child of the new root.
- Update the heights of the nodes.
- Left Rotation:
- Make the right child of the current node the new root of the subtree.
- Make the old root the left child of the new root.
- Update the heights of the nodes.
C++ Program to Implement Balanced Binary Tree
The following program demonstrates the implementation of a Balanced Binary Tree in C++.
C++
// C++ Program to Implement Balanced Binary Tree
#include <algorithm>
#include <iostream>
using namespace std;
template <typename T> class BalancedBinaryTree {
private:
// Node structure definition
struct Node {
T data;
Node* left;
Node* right;
int height;
Node(T value)
: data(value)
, left(nullptr)
, right(nullptr)
, height(1)
{
}
};
Node* root;
// Function to get the height of the node
int height(Node* node)
{
return node ? node->height : 0;
}
// Function to get the balance factor of the node
int balanceFactor(Node* node)
{
return node ? height(node->left)
- height(node->right)
: 0;
}
// Function to update the height of the node
void updateHeight(Node* node)
{
node->height = 1
+ max(height(node->left),
height(node->right));
}
// Right rotation function
Node* rotateRight(Node* y)
{
Node* x = y->left;
Node* T2 = x->right;
x->right = y;
y->left = T2;
updateHeight(y);
updateHeight(x);
return x;
}
// Left rotation function
Node* rotateLeft(Node* x)
{
Node* y = x->right;
Node* T2 = y->left;
y->left = x;
x->right = T2;
updateHeight(x);
updateHeight(y);
return y;
}
// Function to insert a node
Node* insert(Node* node, T key)
{
// Perform the normal BST insertion
if (!node)
return new Node(key);
if (key < node->data)
node->left = insert(node->left, key);
else if (key > node->data)
node->right = insert(node->right, key);
else
return node; // Duplicate keys are not allowed
// Update height of this ancestor node
updateHeight(node);
// Get the balance factor to check whether this node
// became unbalanced
int balance = balanceFactor(node);
// If the node becomes unbalanced, there are 4 cases
// Left Left Case
if (balance > 1 && key < node->left->data)
return rotateRight(node);
// Right Right Case
if (balance < -1 && key > node->right->data)
return rotateLeft(node);
// Left Right Case
if (balance > 1 && key > node->left->data) {
node->left = rotateLeft(node->left);
return rotateRight(node);
}
// Right Left Case
if (balance < -1 && key < node->right->data) {
node->right = rotateRight(node->right);
return rotateLeft(node);
}
return node;
}
// Function to find the node with the minimum value
// (used in deletion)
Node* findMin(Node* node)
{
while (node->left)
node = node->left;
return node;
}
// Function to delete a node
Node* remove(Node* node, T key)
{
// Perform standard BST delete
if (!node)
return nullptr;
if (key < node->data)
node->left = remove(node->left, key);
else if (key > node->data)
node->right = remove(node->right, key);
else {
if (!node->left || !node->right) {
Node* temp
= node->left ? node->left : node->right;
if (!temp) {
temp = node;
node = nullptr;
}
else
*node = *temp;
delete temp;
}
else {
Node* temp = findMin(node->right);
node->data = temp->data;
node->right
= remove(node->right, temp->data);
}
}
if (!node)
return nullptr;
// Update height of the current node
updateHeight(node);
// Get the balance factor
int balance = balanceFactor(node);
// Balance the node if it has become unbalanced
// Left Left Case
if (balance > 1 && balanceFactor(node->left) >= 0)
return rotateRight(node);
// Left Right Case
if (balance > 1 && balanceFactor(node->left) < 0) {
node->left = rotateLeft(node->left);
return rotateRight(node);
}
// Right Right Case
if (balance < -1 && balanceFactor(node->right) <= 0)
return rotateLeft(node);
// Right Left Case
if (balance < -1
&& balanceFactor(node->right) > 0) {
node->right = rotateRight(node->right);
return rotateLeft(node);
}
return node;
}
// Function to search for a key in the tree
bool search(Node* node, T key)
{
if (!node)
return false;
if (node->data == key)
return true;
if (key < node->data)
return search(node->left, key);
return search(node->right, key);
}
// Function for inorder traversal of the tree
void inorderTraversal(Node* node)
{
if (node) {
inorderTraversal(node->left);
cout << node->data << " ";
inorderTraversal(node->right);
}
}
public:
// Constructor
BalancedBinaryTree()
: root(nullptr)
{
}
// Public insert function
void insert(T key) { root = insert(root, key); }
// Public remove function
void remove(T key) { root = remove(root, key); }
// Public search function
bool search(T key) { return search(root, key); }
// Public function to print the inorder traversal
void printInorder()
{
inorderTraversal(root);
cout << endl;
}
};
int main()
{
BalancedBinaryTree<int> tree;
// Insert elements
tree.insert(10);
tree.insert(20);
tree.insert(30);
tree.insert(40);
tree.insert(50);
tree.insert(25);
cout << "Inorder traversal of the constructed Balanced "
"Binary Tree"
<< endl;
tree.printInorder();
// Search for a key
int searchKey = 30;
cout << "Searching for key " << searchKey << ": "
<< (tree.search(searchKey) ? "Found" : "Not Found")
<< endl;
// Remove a key
int removeKey = 20;
tree.remove(removeKey);
cout << "Inorder traversal after removing " << removeKey
<< ": ";
tree.printInorder();
return 0;
}
OutputInorder traversal of the constructed Balanced Binary Tree
10 20 25 30 40 50
Searching for key 30: Found
Inorder traversal after removing 20: 10 25 30 40 50
Applications of Balanced Binary Trees
Following are some of the common applications of balanced binary trees:
- Many database systems use balanced trees (like B-trees, which are a generalization of balanced binary trees) for efficient indexing.
- Some file systems use balanced trees to organize directory structures.
- Some memory allocators use balanced trees to keep track of free memory blocks.
- Balanced binary trees can be used to represent and evaluate arithmetic expressions.
- Balanced trees can be used to implement efficient lookup tables for network routing.
Similar Reads
Balanced Binary Tree
A binary tree is balanced if the height of the tree is O(Log n) where n is the number of nodes. For Example, the AVL tree maintains O(Log n) height by making sure that the difference between the heights of the left and right subtrees is at most 1. Red-Black trees maintain O(Log n) height by making s
3 min read
Binary Tree in C
A binary tree is a non-linear hierarchical data structure in which each node has at most two children known as the left child and the right child. It can be visualized as a hierarchical structure where the topmost node is called the root node and the nodes at the bottom are called leaf nodes or leav
12 min read
Balanced Binary Tree definition & meaning in DSA
Balanced binary tree is defined as a binary tree data structure where there is no more than one height difference between the left and right subtrees of any given node. Mathematically Height of left subtree - Height of right subtree â¤1 Balanced and Unbalanced Binary TreeProperties of Balanced Binary
2 min read
Create a balanced BST using vector in C++ STL
Given an unsorted vector arr, the task is to create a balanced binary search tree using the elements of the array. Note: There can be more than one balanced BST. Forming any is acceptable Examples: Input: arr[] = { 2, 1, 3}Output: 2 1 3Explanation: The tree formed is show below. The preorder travers
5 min read
B-Tree Implementation in C++
In C++, B-trees are balanced tree data structures that maintain sorted data and allow searches, sequential access, insertions, and deletions in logarithmic time. B-trees are generalizations of binary search trees (BST) in that a node can have more than two children. B-trees are optimized for systems
13 min read
KD Trees in C++
A KD Tree (k-dimensional tree) is a space-partitioning data structure for organizing points in a k-dimensional space. This structure is particularly useful for applications involving multidimensional search keys, such as range searches and nearest neighbor searches.In this article, we will learn how
7 min read
Implementation of B+ Tree in C
A B+ tree is a self-balancing tree data structure that maintains sorted data and allows searching, inserting, and deletion of data in logarithmic time. In B+ trees, the actual data is stored inside the leaf nodes and the internal nodes act as pointers to the leaf nodes. In this article, we will lear
15+ min read
Implementation of B-Tree in C
The B-tree is a self-balancing ordered structured data that stores data in a set of pages and also allows efficient searching, insertion, and deletion operations. It has its origin in a generic form of binary search trees developed by Rudolf Bayer and Edward M. McCreight in 1972. It is capable of pr
5 min read
Introduction to Link-Cut Tree
Link Cut Trees (LCT) is a data structure that allows for efficient dynamic maintenance of trees. It is a type of self-adjusting data structure that allows for efficient manipulation of trees, such as link and cut operations, find-root, and access. The implementation of an LCT typically consists of a
15 min read
Segment Tree in C++
A Segment Tree is a data structure that is used for various range query problems, particularly in competitive programming. It allows for efficient query operations on arrays, such as finding the minimum, maximum, or sum of elements in a given range. In this article, we will learn how to implement a
7 min read