Binary Search Tree in C++
Last Updated :
28 May, 2024
A Binary Search Tree (BST) is a type of binary tree in which the data is organized and stored in a sorted order. Unlike, a binary tree that doesn't follow a specific order for node placement, in a binary search tree all the elements on the left side of a node are smaller than the node itself, and elements on the right side of a node are greater.
In this article, we will learn more about the binary search tree, operations performed on BST, and implementation of BST, as well as the advantages, disadvantages, and applications of binary search tree in C++.
What is a Binary Search Tree (BST)?
A Binary Search Tree (BST) is a binary tree in which every node contains only smaller values in its left subtree and only larger values in its right subtree. This property is called the BST property and every binary search tree follows this property as it allows efficient insertion, deletion, and search operations in a tree.
Conditions for a Tree to be a Binary Search Tree
For a tree to be called a binary search, it should fulfill the following conditions:
- All the nodes in the left subtree of any node contain smaller values and all the nodes in the right subtree of any node contain larger values.
- Both the left and right subtrees of any node in the tree should themselves be a BST. This means that they should follow the BST rule.
- A unique path exists from the root node to every other node.
Binary Search Tree Representation in C++
In BST, every value on the left subtree < parent node < right subtree value.
Binary Search Tree
Following are the basics terminologies used in BST:
- Children: The successor nodes of a node are called its children.
- Parent: The predecessor node of a node is called its parent.
- Root: The "beginning" node is called the root i.e. a node that has no parent.
- leaf: A node that has no children is called a leaf.
Basic Operations on Binary Search Tree
The following are the basics operations performed on a binary search tree:
Here, we will discuss the basic three operation: search, insertion and deletion in a binary search tree.
Operation
| Description
| Best Case Time Complexity
| Average Case Time Complexity
| Worse Case Time Complexity
|
---|
Search
| This function is used to search a given key in BST.
| O(log n)
| O(log n)
| O(n)
|
---|
Insertion
| This function is used to insert values in a BST.
| O(log n)
| O(log n)
| O(n)
|
---|
Deletion
| This function is used to delete the specified node from a BST.
| O(log n)
| O(log n)
| O(n)
|
---|
The space complexity for all the above operations is O(n).
1. Searching in Binary Search Tree
To search for a given key in a binary search tree, follow the below approach:
Approach:
- Start from root of BST.
- Compare the target value (value you want to search) with the root node's value:
- If the target value is equal to root node's value. Return true,
- If the target value is less than root node's value, then recurse for left as smaller values lie on leftsubtree in BST.
- Else if the target value is greater than root node's value, then recurse for right as larger value lie on rightsubtree in BST.
- Repeat the above step till no more traversal is possible
- If the target element is found anywhere, return true, else return false
2. Insertion in Binary Search Tree
In BST a new key is always inserted at leaf and property of binary search tree should be maintained. To insert a given key in a binary search tree, follow the below approach:
Approach:
- Traverse the tree to find the insertion point by comparing the value to be inserted(target value) with the current node's value. I
- If the target value is less than current node's value move to left subtree.
- If the target value is more than current node's value move to right subtree.
- Repeat the above steps until the leaf node is reached.
- Insert the new node with a target value. If the target value is less than parent node's value, insert it on the left, otherwise insert it on the right.
3. Deletion in Binary Search Tree
We have the following 3 cases while deleting a node from BST:
- Deleting a leaf node.
- Deleting a node having single child.
- Deletion a node having both children.
Approach:
- Start from the root node and search for the target node (node to be deleted), move to left if target node is less than current node and move to the right if target node is greater than current node. Repeat this step until target node is found or null node is reached.
- When the target node is found Handle the following 3 cases for deletion:
- If a target node is leaf node, simply delete it
- If a target node has 1 child, replace the target node with its child node and delete the target node.
- If a target node has 2 children
- Find the target node's inorder successor.
- Replace the target node with successor.
- Delete the inorder successor.
C++ Program to Implement Binary Search Tree
The below program demonstrates all the major operations on a binary search tree: creation, searching, insertion and deletion.
C++
// C++ Program to implement binary search tree
#include <iostream>
using namespace std;
// Node structure for a Binary Search Tree
struct Node {
int data;
Node* left;
Node* right;
};
// Function to create a new Node
Node* createNode(int data)
{
Node* newNode = new Node();
newNode->data = data;
newNode->left = newNode->right = nullptr;
return newNode;
}
// Function to insert a node in the BST
Node* insertNode(Node* root, int data)
{
if (root == nullptr) { // If the tree is empty, return a
// new node
return createNode(data);
}
// Otherwise, recur down the tree
if (data < root->data) {
root->left = insertNode(root->left, data);
}
else if (data > root->data) {
root->right = insertNode(root->right, data);
}
// return the (unchanged) node pointer
return root;
}
// Function to do inorder traversal of BST
void inorderTraversal(Node* root)
{
if (root != nullptr) {
inorderTraversal(root->left);
cout << root->data << " ";
inorderTraversal(root->right);
}
}
// Function to search a given key in a given BST
Node* searchNode(Node* root, int key)
{
// Base Cases: root is null or key is present at root
if (root == nullptr || root->data == key) {
return root;
}
// Key is greater than root's key
if (root->data < key) {
return searchNode(root->right, key);
}
// Key is smaller than root's key
return searchNode(root->left, key);
}
// Function to find the inorder successor
Node* minValueNode(Node* node)
{
Node* current = node;
// loop down to find the leftmost leaf
while (current && current->left != nullptr) {
current = current->left;
}
return current;
}
// Function to delete a node
Node* deleteNode(Node* root, int data)
{
if (root == nullptr)
return root;
// If the data to be deleted is smaller than the root's
// data, then it lies in the left subtree
if (data < root->data) {
root->left = deleteNode(root->left, data);
}
// If the data to be deleted is greater than the root's
// data, then it lies in the right subtree
else if (data > root->data) {
root->right = deleteNode(root->right, data);
}
// if data is same as root's data, then This is the node
// to be deleted
else {
// node with only one child or no child
if (root->left == nullptr) {
Node* temp = root->right;
delete root;
return temp;
}
else if (root->right == nullptr) {
Node* temp = root->left;
delete root;
return temp;
}
// node with two children: Get the inorder successor
// (smallest in the right subtree)
Node* temp = minValueNode(root->right);
// Copy the inorder successor's content to this node
root->data = temp->data;
// Delete the inorder successor
root->right = deleteNode(root->right, temp->data);
}
return root;
}
// Main function to demonstrate the operations of BST
int main()
{
Node* root = nullptr;
// create a BST
root = insertNode(root, 50);
root = insertNode(root, 30);
root = insertNode(root, 20);
root = insertNode(root, 40);
root = insertNode(root, 70);
root = insertNode(root, 60);
root = insertNode(root, 80);
// Print the inorder traversal of a BST
cout << "Inorder traversal of the given Binary Search "
"Tree is: ";
inorderTraversal(root);
cout << endl;
// delete a node in BST
root = deleteNode(root, 20);
cout << "After deletion of 20: ";
inorderTraversal(root);
cout << endl;
// Insert a node in BST
root = insertNode(root, 25);
cout << "After insertion of 25: ";
inorderTraversal(root);
cout << endl;
// Search a key in BST
Node* found = searchNode(root, 25);
// check if the key is found or not
if (found != nullptr) {
cout << "Node 25 found in the BST." << endl;
}
else {
cout << "Node 25 not found in the BST." << endl;
}
return 0;
}
OutputInorder traversal of the given Binary Search Tree is: 20 30 40 50 60 70 80
After deletion of 20: 30 40 50 60 70 80
After insertion of 25: 25 30 40 50 60 70 80
Node 25 found in the BST.
Time Complexity:
Auxilliary Space:
The average time complexity for all three operations on BST is O (log n). In the worst case (Skewed BST) the time complexity can become O (n). n = number of nodes.The Space complexity for all three operations done on BST is O (1). This means no extra space or memory is required to perform these operations on a BST.
Applications of Binary Search Tree
Following are the applications of binary search tree:
- BST can be used to find(an element) and sort a collection of elements in ascending or descending order and for in it.
- BSTs are used to implement priority queues where elements are inserted based on their priority number.
- BSTs are widely used in symbol tables inside compilers.
- BST can also be used to store large datasets using a particular sort key. So, searching and accessing a specific element becomes much faster.
- The Decision trees and rule-based systems in AI use Binary search trees.
- It can be used in databases for multilevel indexing.
Advantages of Binary Search Tree
- Because of the unique properties of BST, it provides an efficient way to search an element having O(log n) time complexity.
- The In-Order Traversal of BST is always in a sorted order. So, it becomes easier to retrieve elements in sorted order in a BST.
- It can adapt to various applications by defining a custom node structure.
- Balanced Binary search tree have logarithmic height that ensures efficient operations.
- It stores only the key values, that makes them space-efficient.
Disadvantages of Binary Search Tree
- The performance of BST depends upon its balance.
- Skewed BST is the worst-case scenario where the search complexity becomes O(n), just like any other tree.
- Although operations like insertion and deletion are easy in BST, maintaining the balance of the tree is hard.
- If the tree is made by using a sorted list, then the creation can lead to a highly unbalanced BST which degrades its performance. One solution is to balance the tree after every insertion.
- Binary search tree become less efficient for very large datasets
Similar Reads
Non-linear Components
In electrical circuits, Non-linear Components are electronic devices that need an external power source to operate actively. Non-Linear Components are those that are changed with respect to the voltage and current. Elements that do not follow ohm's law are called Non-linear Components. Non-linear Co
11 min read
C++ Programming Language
C++ is a computer programming language developed by Bjarne Stroustrup as an extension of the C language. It is known for is fast speed, low level memory management and is often taught as first programming language. It provides: Hands-on application of different programming concepts.Similar syntax to
5 min read
Class Diagram | Unified Modeling Language (UML)
A UML class diagram is a visual tool that represents the structure of a system by showing its classes, attributes, methods, and the relationships between them. It helps everyone involved in a projectâlike developers and designersâunderstand how the system is organized and how its components interact
12 min read
Object Oriented Programming in C++
Object Oriented Programming - As the name suggests uses objects in programming. Object-oriented programming aims to implement real-world entities like inheritance, hiding, polymorphism, etc. in programming. The main aim of OOP is to bind together the data and the functions that operate on them so th
6 min read
Spring Boot Tutorial
Spring Boot is a Java framework that makes it easier to create and run Java applications. It simplifies the configuration and setup process, allowing developers to focus more on writing code for their applications. This Spring Boot Tutorial is a comprehensive guide that covers both basic and advance
10 min read
Inheritance in C++
The capability of a class to derive properties and characteristics from another class is called Inheritance. Inheritance is one of the most important features of Object-Oriented Programming in C++. In this article, we will learn about inheritance in C++, its modes and types along with the informatio
11 min read
Backpropagation in Neural Network
Backpropagation is also known as "Backward Propagation of Errors" and it is a method used to train neural network . Its goal is to reduce the difference between the modelâs predicted output and the actual output by adjusting the weights and biases in the network. In this article we will explore what
10 min read
AVL Tree Data Structure
An AVL tree defined as a self-balancing Binary Search Tree (BST) where the difference between heights of left and right subtrees for any node cannot be more than one. The absolute difference between the heights of the left subtree and the right subtree for any node is known as the balance factor of
4 min read
3-Phase Inverter
An inverter is a fundamental electrical device designed primarily for the conversion of direct current into alternating current . This versatile device , also known as a variable frequency drive , plays a vital role in a wide range of applications , including variable frequency drives and high power
13 min read
What is Vacuum Circuit Breaker?
A vacuum circuit breaker is a type of breaker that utilizes a vacuum as the medium to extinguish electrical arcs. Within this circuit breaker, there is a vacuum interrupter that houses the stationary and mobile contacts in a permanently sealed enclosure. When the contacts are separated in a high vac
13 min read