A binary tree is a hierarchical data structure in which each node has at most two children, referred to as the left and right child. The topmost node is the root node, and the nodes at the last level having no children are the leaf nodes.
In this article, we will learn about the basics of a binary tree in C++. We will learn how to represent a binary tree, basic operations performed on a binary tree, it's various types and practical applications of binary tree in C.
Implementation of Binary Tree in C++
A binary tree is a tree-based hierarchical data structure where each node can have at most two children. The topmost node is called the root, and nodes with no children are called leaves. To implement a binary tree in C++, we'll use a node-based approach. Each node of the binary tree will contain data and pointers to its left and right children.
Representation of Binary Tree
Binary Tree in C++To represent a binary tree in C++, we will declare a class Node that will consist of data and pointers to left and right children. We will use a template to keep the binary tree generic so that it can store multiple data types. We will also declare a class name BinaryTree to encapsulate the binary tree data members and all its methods.
template <typename T>
class Node {
public:
T data;
Node* left;
Node* right;
Here, each node of a binary tree has the following 3 parts:
- data represents the value stored in the node of the binary tree.
- left is the pointer to the left child of the node.
- right is the pointer to the right child of the node.
To learn more about binary tree refer to this article.
Basic Operations on Binary Tree in C++
Following are some of the basic operations of binary tree that are required to manipulate its elements:
Operation Name | Description | Time Complexity | Space Complexity |
---|
Insertion | Inserts a new node into the binary tree. | O(N) | O(N) |
---|
Deletion | Deletes a specific node from the binary tree. | O(N) | O(N) |
---|
Searching | Searches for a specific value in the binary tree. | O(N) | O(N) |
---|
Traversal | In-order, Pre-order, Post-order traversals | O(N) | O(N) |
---|
1. Insertion in Binary Tree
In a binary tree, we can insert a node anywhere as right child or left child of the node. Following is the algorithm to insert a new node into the binary tree:
Approach:
- Check if the tree is empty:
- If the tree is empty, create a new node and set it as the root.
- Use level order traversal to find the insertion point:
- Initialize a queue and enqueue the root node.
- While the queue is not empty:
- Dequeue a node from the front of the queue.
- If the dequeued node's left child is
NULL
:- Insert the new node as the left child of the dequeued node.
- Break the loop.
- If the dequeued node's right child is
NULL
:- Insert the new node as the right child of the dequeued node.
- Break the loop.
- If both left and right children are not
NULL
, enqueue them.
2. Deletion in Binary Tree
In binary, after deletion of a node we need to rearrange the tree to maintain the property of binary tree. Leaf node can be deleted without any rearrangements. Following is the algorithm to delete a node from the binary tree:
Approach:
- Find the node to be deleted:
- Use level order traversal to find the node with the value to be deleted and the deepest node in the tree.
- Replace the node to be deleted with the deepest node:
- Replace the value of the node to be deleted with the value of the deepest node.
- Delete the deepest node:
- Use level order traversal to find and remove the deepest node in the tree.
3. Searching in Binary Tree
To search a given node in a binary tree, we need to traverse and compare each node with target node (node to be searched). Following is the algorithm to search a node in the binary tree:
Approach:
- Check if the tree is empty:
- If the tree is empty, return
false
.
- Use level order traversal to search for the node:
- Initialize a queue and enqueue the root node.
- While the queue is not empty:
- Dequeue a node from the front of the queue.
- If the dequeued node's value matches the value being searched for, return
true
. - Enqueue the left and right children of the dequeued node if they are not
NULL
.
- If the loop ends and the value was not found, return
false
.
4. Traversals in Binary Tree
Following are the binary tree traversal techniques:
C++ Program for Implementing Binary Tree
The following program illustrates how we can implement a binary tree in C++.
C++
// C++ Program for Implementing Binary Tree
#include <iostream>
#include <queue>
using namespace std;
// Template class for the Node of a Binary Tree
template <typename T>
class Node {
public:
// Data held by the node
T data;
// Pointer to the left child
Node* left;
// Pointer to the right child
Node* right;
// Constructor to initialize the node with a value
Node(T value) : data(value), left(nullptr), right(nullptr) {}
};
// Template class for a Binary Tree
template <typename T>
class BinaryTree {
private:
// Pointer to the root of the tree
Node<T>* root;
// Recursive Function to delete a node from the tree
Node<T>* deleteRecursive(Node<T>* current, T value) {
if (current == nullptr) return nullptr;
if (current->data == value) {
if (current->left == nullptr && current->right == nullptr) {
delete current;
return nullptr;
}
if (current->left == nullptr) {
Node<T>* temp = current->right;
delete current;
return temp;
}
if (current->right == nullptr) {
Node<T>* temp = current->left;
delete current;
return temp;
}
Node<T>* successor = findMin(current->right);
current->data = successor->data;
current->right = deleteRecursive(current->right, successor->data);
} else {
current->left = deleteRecursive(current->left, value);
current->right = deleteRecursive(current->right, value);
}
return current;
}
// Helper Function to find the minimum value node
Node<T>* findMin(Node<T>* node) {
while (node->left != nullptr) node = node->left;
return node;
}
// Recursive Function to search for a value in the tree
bool searchRecursive(Node<T>* current, T value) {
if (current == nullptr) return false;
if (current->data == value) return true;
return searchRecursive(current->left, value) || searchRecursive(current->right, value);
}
// Function for Recursive inorder traversal of the tree
void inorderRecursive(Node<T>* node) {
if (node != nullptr) {
inorderRecursive(node->left);
cout << node->data << " ";
inorderRecursive(node->right);
}
}
// Function for Recursive preorder traversal of the tree
void preorderRecursive(Node<T>* node) {
if (node != nullptr) {
cout << node->data << " ";
preorderRecursive(node->left);
preorderRecursive(node->right);
}
}
// Function for Recursive postorder traversal of the tree
void postorderRecursive(Node<T>* node) {
if (node != nullptr) {
postorderRecursive(node->left);
postorderRecursive(node->right);
cout << node->data << " ";
}
}
public:
// Constructor to initialize the tree
BinaryTree() : root(nullptr) {}
// Function to insert a node in the binary tree
void insertNode(T value) {
Node<T>* newNode = new Node<T>(value);
if (root == nullptr) {
root = newNode;
return;
}
queue<Node<T>*> q;
q.push(root);
while (!q.empty()) {
Node<T>* current = q.front();
q.pop();
if (current->left == nullptr) {
current->left = newNode;
return;
} else {
q.push(current->left);
}
if (current->right == nullptr) {
current->right = newNode;
return;
} else {
q.push(current->right);
}
}
}
// Function to delete a node from the tree
void deleteNode(T value) {
root = deleteRecursive(root, value);
}
// Function to search for a value in the tree
bool search(T value) {
return searchRecursive(root, value);
}
// Function to perform inorder traversal of the tree
void inorder() {
inorderRecursive(root);
cout << endl;
}
// Function to perform preorder traversal of the tree
void preorder() {
preorderRecursive(root);
cout << endl;
}
// Function to perform postorder traversal of the tree
void postorder() {
postorderRecursive(root);
cout << endl;
}
// Function to perform level order traversal of the tree
void levelOrder() {
if (root == nullptr) return;
queue<Node<T>*> q;
q.push(root);
while (!q.empty()) {
Node<T>* current = q.front();
q.pop();
cout << current->data << " ";
if (current->left != nullptr) q.push(current->left);
if (current->right != nullptr) q.push(current->right);
}
cout << endl;
}
};
int main() {
BinaryTree<int> tree;
// Insert the nodes into the tree
tree.insertNode(1);
tree.insertNode(2);
tree.insertNode(3);
tree.insertNode(4);
tree.insertNode(5);
tree.insertNode(6);
cout << "Inorder traversal: ";
tree.inorder();
cout << "Preorder traversal: ";
tree.preorder();
cout << "Postorder traversal: ";
tree.postorder();
cout << "Level order traversal: ";
tree.levelOrder();
cout << "Searching for 7: " << (tree.search(7) ? "Found" : "Not Found") << endl;
cout << "Searching for 6: " << (tree.search(6) ? "Found" : "Not Found") << endl;
tree.deleteNode(3);
cout << "Inorder traversal after removing 3: ";
tree.inorder();
return 0;
}
Output
Inorder traversal: 4 2 5 1 6 3
Preorder traversal: 1 2 4 5 3 6
Postorder traversal: 4 5 2 6 3 1
Level order traversal: 1 2 3 4 5 6
Searching for 7: Not Found
Searching for 6: Found
Inorder traversal after removing 3: 4 2 5 1 6
Types of Binary Tree in C++
Following are the types of Binary Trees according to various factors:
According to Number of Children
- Full Binary Tree: A full binary tree is a tree in which every node has either 0 or 2 children. In other words, all nodes except leaf nodes have two children.
- Degenerate Binary Tree: A degenerate binary tree is similar to a skewed binary tree. It's a tree where each parent node has only one child node.
- Skewed Binary Tree: A skewed binary tree is a tree in which all nodes have only one child, either left or right. There are two types: left-skewed and right-skewed.
According to Completion of Levels
- Complete Binary Tree: A complete binary tree is a binary tree in which all levels are completely filled except possibly the last level, which is filled from left to right.
- Perfect Binary Tree: A perfect binary tree is a binary tree in which all interior nodes have two children and all leaves are at the same level.
- Balanced Binary Tree: A balanced binary tree is a binary tree in which the height of the left and right subtrees of every node differs by at most one.
According to Node Values
- Binary Search Tree: A Binary Search Tree is a binary tree where for each node, all elements in the left subtree are less than the node, and all elements in the right subtree are greater than the node.
- AVL Tree: An AVL tree is a self-balancing BST where the height of the left and right subtrees of any node differ by at most one.
- Red Black Tree: A Red-Black tree is a self-balancing BST where each node has an extra bit for denoting the color of the node, either red or black.
- B Tree: B-tree is a self-balancing tree data structure that maintains sorted data and allows searches, sequential access, insertions, and deletions in logarithmic time.
- B+ Tree: A B+ tree is a variant of the B-tree that has all data stored in the leaf nodes, while internal nodes only store keys.
- Segment Tree: A Segment Tree is a tree data structure used for storing information about intervals, or segments. It allows querying which of the stored segments contain a given point.
- Fenwick Tree: A Fenwick Tree is a data structure that can efficiently update elements and calculate prefix sums in a table of numbers.
Applications of Binary Tree
Following are some common applications of Binary Trees:
- File System Organization: Binary trees are used to represent hierarchical file structures.Each node in the tree represents a directory or a file, with the root node typically representing the main directory. Child nodes represent subdirectories or files within a directory.
- Expression Trees: In compilers and interpreters, expression trees are used to represent and evaluate arithmetic or logical expressions. Each internal node represents an operator (+, -, *, /, etc.), while leaf nodes represent operands (numbers or variables). This structure allows for easy parsing, evaluation, and optimization of mathematical expressions.
- Huffman Coding Trees: Huffman coding is a data compression algorithm that uses a binary tree structure. The tree is constructed based on the frequency of characters in the data. More frequent characters are assigned shorter codes, while less frequent ones get longer codes. This results in efficient data compression, especially for text files.
- Binary Search Trees: BSTs are a special type of binary tree where for each node, all elements in the left subtree are smaller, and all elements in the right subtree are larger. This property makes BSTs extremely efficient for searching, insertion, and deletion operations, typically with O(log n) time complexity in balanced cases.
- Decision Trees: In machine learning, decision trees are used for classification and regression tasks. Each internal node represents a "test" on an attribute, each branch represents the outcome of the test, and each leaf node represents a class label or a numerical output. Decision trees are popular due to their interpretability and ability to handle both numerical and categorical data.
- Game Trees: In artificial intelligence, particularly for game strategy planning, game trees represent all possible moves and their outcomes in a game. Each level of the tree represents a player's turn, and leaf nodes represent final game states
- Syntax Trees: Compilers use syntax trees (also known as abstract syntax trees or ASTs) to represent the structure of program code. Each node in the tree represents a construct in the source code, such as functions, loops, or conditional statements. This representation helps in code analysis, optimization, and generation of machine code.
Similar Reads
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 in C++
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
8 min read
What is Binary Tree?
A binary tree is a type of tree data structure in which each node can have at most two child nodes, known as the left child and the right child. Each node of the tree consists of - data and pointers to the left and the right child. Properties of a Binary Tree: The following are some of the important
3 min read
What is Binary Code?
Two States the digital systems, and computers are written in its basic language. Binary code It is a digital encoding of an analog signal wherein it uses a two-symbol system, â0â and â1â, to represent text, computer processor instructions, or any other data. A bit short for "binary digit", is the ba
9 min read
STD::array in C++
The array is a collection of homogeneous objects and this array container is defined for constant size arrays or (static size). This container wraps around fixed-size arrays and the information of its size are not lost when declared to a pointer. In order to utilize arrays, we need to include the ar
5 min read
What is Binary String?
A binary string is a string that only has two characters, usually the numbers 0 and 1, and it represents a series of binary digits. Binary String Variables:In computer programming, binary string variables are used to store binary data, which is data that is represented in a binary (base-2) format, r
9 min read
Binary Heap in Python
A Binary Heap is a complete Binary Tree that is used to store data efficiently to get the max or min element based on its structure. A Binary Heap is either a Min Heap or a Max Heap. In a Min Binary Heap, the key at the root must be minimum among all keys present in a Binary Heap. The same property
3 min read
What is Binary Heap
Binary heap is a complete binary tree where the root of any subtree has a higher (or lower based on the type of heap) value than all the nodes in its subtree. Characteristics of Binary Heap: The following are the properties of a binary heap: It is a complete binary tree, which means that all levels
2 min read
std::bsearch in C++
std::bsearch searches for an element in a sorted array. It performs binary search on the sorted array to search for an element. The std::search function is defined inside the <cstdlib> header file. Syntaxvoid* bsearch(const void* key, const void* ptr, size_t num, size_t size, int (*comp)(const
4 min read
Binary Number System
Binary Number System uses two digits, '0' and '1', and is the foundation for all modern computing. The word binary is derived from the word "bi," which means two. But what makes it so essential, and how does it work? This article will dive deep into binary numbers, binary decimal number conversion a
7 min read