Deletion in a Binary Tree in C++?


The deletion is to be performed by replacing the deleted mode by bottom and rightmost node.

Let us first define the struct that would represent a tree node that contains the data and its left and right node child. If this is the first node to be created then it’s a root node otherwise a child node.

struct Node {
   int data;
   struct Node *leftChild, *rightChild;
};

Next we create our newNode(int data) function that takes an int value and assign it to the data member of the node. The function returns the pointer to the created struct Node. Also, the left and right child of the newly created node are set to null.

struct Node* newNode(int data){
   struct Node* newNode = new Node;
   newNode->data = data;
   newNode->leftChild = newNode->rightChild = NULL;
   return (newNode);
}

The deletion(struct Node* root, int data) function is used for deleting the node with the given data value. It takes the root node and the data value to be searched and deleted. If there isn’t any child node and the data value is equal to root’s data value then null is returned else the root node is returned.

Node* deletion(struct Node* root, int data){
   if (root == NULL)
      return NULL;
   if (root->leftChild == NULL && root->rightChild == NULL) {
      if (root->data == data)
         return NULL;
      else
         return root;
   }

Now we make a queue of type struct Node * and name it q and push the root node to the q. We also declare temp and data_node which are pointers to Node and set the data_node as NULL.

struct Node* temp;
struct Node* data_node = NULL;

Next, we perform level order traversal to find the deepest node. The while loop is executed till the queue q isn’t empty. Queue is a FIFO data structure so the last element in the queue will be the rightmost deepest node as we are going by level order traversal. The temp points to the front of the queue always and elements are popped from front as we go on.

while (!q.empty()) {
   temp = q.front();
   q.pop();
   if (temp->data == data)
      data_node = temp;
   if (temp->leftChild)
      q.push(temp->leftChild);
   if (temp->rightChild)
   q.push(temp->rightChild);
}

Next if the data_node isn’t NULL then we store the node to be deleted data in x and delete the temp which is the deepest node. The data_node value is then replaced with the deepest node value and the deepest node is deleted. The new node is returned from the function after the deletion and replacement.

if (data_node != NULL) {
   int x = temp->data;
   deleteDeepest(root, temp);
   data_node->data = x;
}

The deleteDeepest(struct Node* root,struct Node* deepestNode) function checks if the passed node is actually the deepest node or it’s right or left child is the deepest node in which case it sets the child value to null before deleting the parent which is the deepestNode.

void deleteDeepest(struct Node* root,
   struct Node* deepestNode){
      queue<struct Node*> q;
      q.push(root);
      struct Node* temp;
      while (!q.empty()) {
         temp = q.front();
         q.pop();
      if (temp == deepestNode) {
         temp = NULL;
         delete (deepestNode);
         return;
      }
      if (temp->rightChild) {
         if (temp->rightChild == deepestNode) {
            temp->rightChild = NULL;
            delete (deepestNode);
            return;
         }
         else
            q.push(temp->rightChild);
         }
      if (temp->leftChild) {
         if (temp->leftChild == deepestNode) {
            temp->leftChild = NULL;
            delete (deepestNode);
            return;
         }
         else
            q.push(temp->leftChild);
      }
   }
}

Example

Let us see the following implementation to see the deletion in the binary tree −

 Live Demo

#include <iostream>
#include <queue>
using namespace std;
struct Node {
   int data;
   struct Node *leftChild, *rightChild;
};
struct Node* NewNode(int data){
   struct Node* temp = new Node;
   temp->data = data;
   temp->leftChild = temp->rightChild = NULL;
   return temp;
};
void inorder(struct Node* temp){
   if (!temp)
      return;
   inorder(temp->leftChild);
   cout << temp->data << " ";
   inorder(temp->rightChild);
}
void deleteDeepest(struct Node* root,
   struct Node* deepestNode){
      queue<struct Node*> q;
      q.push(root);
      struct Node* temp;
      while (!q.empty()) {
         temp = q.front();
         q.pop();
         if (temp == deepestNode) {
            temp = NULL;
            delete (deepestNode);
            return;
         }
         if (temp->rightChild) {
            if (temp->rightChild == deepestNode) {
               temp->rightChild = NULL;
               delete (deepestNode);
               return;
            }
            else
               q.push(temp->rightChild);
         }
         if (temp->leftChild) {
            if (temp->leftChild == deepestNode) {
               temp->leftChild = NULL;
               delete (deepestNode);
               return;
            }
         else
            q.push(temp->leftChild);
         }
      }
   }
Node* deletion(struct Node* root, int data){
   if (root == NULL)
      return NULL;
   if (root->leftChild == NULL && root->rightChild == NULL) {
      if (root->data == data)
         return NULL;
      else
         return root;
   }
   queue<struct Node*> q;
   q.push(root);  
   struct Node* temp;
   struct Node* data_node = NULL;
while (!q.empty()) {
   temp = q.front();
   q.pop();
   if (temp->data == data)
      data_node = temp;
   if (temp->leftChild)
      q.push(temp->leftChild);
   if (temp->rightChild)
      q.push(temp->rightChild);
}
if (data_node != NULL) {
   int x = temp->data;
   deleteDeepest(root,temp);
   data_node->data = x;
   }
   return root;
}
// Driver code
int main(){
   struct Node* root = NewNode(12);
   root->leftChild = NewNode(13);
   root->leftChild->leftChild = NewNode(9);
   root->leftChild->rightChild = NewNode(14);
   root->rightChild = NewNode(11);
   root->rightChild->leftChild = NewNode(17);
   root->rightChild->rightChild = NewNode(10);
   cout << "Inorder traversal before deletion : ";
   inorder(root);
   int data = 13;
   root = deletion(root, data);
   cout <<endl<< "Inorder traversal after deletion : ";
   inorder(root);
   return 0;
}

Output

The above code will produce the following output −

Inorder traversal before deletion : 9 13 14 12 17 11 10
Inorder traversal after deletion : 9 10 14 12 17 11

Updated on: 16-Jan-2021

170 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements