Open In App

Deletion in Binary Search Tree (BST)

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Given a BST, the task is to delete a node in this BST, which can be broken down into 3 scenarios:

Case 1. Delete a Leaf Node in BST

d1

Deletion in BST

Case 2. Delete a Node with Single Child in BST

Deleting a single child node is also simple in BST. Copy the child to the node and delete the node

file

Deletion in BST

Case 3. Delete a Node with Both Children in BST

Deleting a node with both children is not so simple. Here we have to delete the node is such a way, that the resulting tree follows the properties of a BST.  

The trick is to find the inorder successor of the node. Copy contents of the inorder successor to the node, and delete the inorder successor.

Note: Inorder predecessor can also be used.

d3

Deletion in Binary Tree

Note: Inorder successor is needed only when the right child is not empty. In this particular case, the inorder successor can be obtained by finding the minimum value in the right child of the node.

Recommended Practice

Implementation of Deletion operation in a BST:

C++




// C++ program to implement optimized delete in BST.
#include <bits/stdc++.h>
using namespace std;
 
struct Node {
    int key;
    struct Node *left, *right;
};
 
// A utility function to create a new BST node
Node* newNode(int item)
{
    Node* temp = new Node;
    temp->key = item;
    temp->left = temp->right = NULL;
    return temp;
}
 
// A utility function to do inorder traversal of BST
void inorder(Node* root)
{
    if (root != NULL) {
        inorder(root->left);
        printf("%d ", root->key);
        inorder(root->right);
    }
}
 
/* A utility function to insert a new node with given key in
 * BST */
Node* insert(Node* node, int key)
{
    /* If the tree is empty, return a new node */
    if (node == NULL)
        return newNode(key);
 
    /* Otherwise, recur down the tree */
    if (key < node->key)
        node->left = insert(node->left, key);
    else
        node->right = insert(node->right, key);
 
    /* return the (unchanged) node pointer */
    return node;
}
 
/* Given a binary search tree and a key, this function
   deletes the key and returns the new root */
Node* deleteNode(Node* root, int k)
{
    // Base case
    if (root == NULL)
        return root;
 
    // Recursive calls for ancestors of
    // node to be deleted
    if (root->key > k) {
        root->left = deleteNode(root->left, k);
        return root;
    }
    else if (root->key < k) {
        root->right = deleteNode(root->right, k);
        return root;
    }
 
    // We reach here when root is the node
    // to be deleted.
 
    // If one of the children is empty
    if (root->left == NULL) {
        Node* temp = root->right;
        delete root;
        return temp;
    }
    else if (root->right == NULL) {
        Node* temp = root->left;
        delete root;
        return temp;
    }
 
    // If both children exist
    else {
 
        Node* succParent = root;
 
        // Find successor
        Node* succ = root->right;
        while (succ->left != NULL) {
            succParent = succ;
            succ = succ->left;
        }
 
        // Delete successor.  Since successor
        // is always left child of its parent
        // we can safely make successor's right
        // right child as left of its parent.
        // If there is no succ, then assign
        // succ->right to succParent->right
        if (succParent != root)
            succParent->left = succ->right;
        else
            succParent->right = succ->right;
 
        // Copy Successor Data to root
        root->key = succ->key;
 
        // Delete Successor and return root
        delete succ;
        return root;
    }
}
 
// Driver Code
int main()
{
    /* Let us create following BST
              50
           /     \
          30      70
         /  \    /  \
       20   40  60   80 */
    Node* root = NULL;
    root = insert(root, 50);
    root = insert(root, 30);
    root = insert(root, 20);
    root = insert(root, 40);
    root = insert(root, 70);
    root = insert(root, 60);
 
    printf("Original BST: ");
    inorder(root);
   
    printf("\n\nDelete a Leaf Node: 20\n");
    root = deleteNode(root, 20);
    printf("Modified BST tree after deleting Leaf Node:\n");
    inorder(root);
 
    printf("\n\nDelete Node with single child: 70\n");
    root = deleteNode(root, 70);
    printf("Modified BST tree after deleting single child Node:\n");
    inorder(root);
 
    printf("\n\nDelete Node with both child: 50\n");
    root = deleteNode(root, 50);
    printf("Modified BST tree after deleting both child Node:\n");
    inorder(root);
 
    return 0;
}


C




// C program to implement optimized delete in BST.
#include <stdio.h>
#include <stdlib.h>
 
struct Node {
    int key;
    struct Node *left, *right;
};
 
// A utility function to create a new BST node
struct Node* newNode(int item)
{
    struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
    temp->key = item;
    temp->left = temp->right = NULL;
    return temp;
}
 
// A utility function to do inorder traversal of BST
void inorder(struct Node* root)
{
    if (root != NULL) {
        inorder(root->left);
        printf("%d ", root->key);
        inorder(root->right);
    }
}
 
/* A utility function to insert a new node with given key in
 * BST */
struct Node* insert(struct Node* node, int key)
{
    /* If the tree is empty, return a new node */
    if (node == NULL)
        return newNode(key);
 
    /* Otherwise, recur down the tree */
    if (key < node->key)
        node->left = insert(node->left, key);
    else
        node->right = insert(node->right, key);
 
    /* return the (unchanged) node pointer */
    return node;
}
 
/* Given a binary search tree and a key, this function
   deletes the key and returns the new root */
struct Node* deleteNode(struct Node* root, int k)
{
    // Base case
    if (root == NULL)
        return root;
 
    // Recursive calls for ancestors of
    // node to be deleted
    if (root->key > k) {
        root->left = deleteNode(root->left, k);
        return root;
    }
    else if (root->key < k) {
        root->right = deleteNode(root->right, k);
        return root;
    }
 
    // We reach here when root is the node
    // to be deleted.
 
    // If one of the children is empty
    if (root->left == NULL) {
        struct Node* temp = root->right;
        free(root);
        return temp;
    }
    else if (root->right == NULL) {
        struct Node* temp = root->left;
        free(root);
        return temp;
    }
 
    // If both children exist
    else {
 
        struct Node* succParent = root;
 
        // Find successor
        struct Node* succ = root->right;
        while (succ->left != NULL) {
            succParent = succ;
            succ = succ->left;
        }
 
        // Delete successor.  Since successor
        // is always left child of its parent
        // we can safely make successor's right
        // right child as left of its parent.
        // If there is no succ, then assign
        // succ->right to succParent->right
        if (succParent != root)
            succParent->left = succ->right;
        else
            succParent->right = succ->right;
 
        // Copy Successor Data to root
        root->key = succ->key;
 
        // Delete Successor and return root
        free(succ);
        return root;
    }
}
 
// Driver Code
int main()
{
    /* Let us create following BST
              50
           /     \
          30      70
         /  \    /  \
       20   40  60   80 */
    struct Node* root = NULL;
    root = insert(root, 50);
    root = insert(root, 30);
    root = insert(root, 20);
    root = insert(root, 40);
    root = insert(root, 70);
    root = insert(root, 60);
 
    printf("Original BST: ");
    inorder(root);
   
    printf("\n\nDelete a Leaf Node: 20\n");
    root = deleteNode(root, 20);
    printf("Modified BST tree after deleting Leaf Node:\n");
    inorder(root);
 
    printf("\n\nDelete Node with single child: 70\n");
    root = deleteNode(root, 70);
    printf("Modified BST tree after deleting single child Node:\n");
    inorder(root);
 
    printf("\n\nDelete Node with both child: 50\n");
    root = deleteNode(root, 50);
    printf("Modified BST tree after deleting both child Node:\n");
    inorder(root);
 
    return 0;
}


Java




// Java program to implement optimized delete in BST.
import java.util.*;
 
class Node {
    int key;
    Node left, right;
 
    // A utility function to create a new BST node
    Node(int item) {
        key = item;
        left = right = null;
    }
}
 
class BST {
    Node root;
 
    // A utility function to do inorder traversal of BST
    void inorder(Node root) {
        if (root != null) {
            inorder(root.left);
            System.out.print(root.key + " ");
            inorder(root.right);
        }
    }
 
    /* A utility function to insert a new node with given key in
     * BST */
    Node insert(Node node, int key) {
        /* If the tree is empty, return a new node */
        if (node == null)
            return new Node(key);
 
        /* Otherwise, recur down the tree */
        if (key < node.key)
            node.left = insert(node.left, key);
        else if (key > node.key)
            node.right = insert(node.right, key);
 
        /* return the (unchanged) node pointer */
        return node;
    }
 
    /* Given a binary search tree and a key, this function
       deletes the key and returns the new root */
    Node deleteNode(Node root, int key) {
        // Base case
        if (root == null)
            return root;
 
        // Recursive calls for ancestors of
        // node to be deleted
        if (root.key > key) {
            root.left = deleteNode(root.left, key);
            return root;
        } else if (root.key < key) {
            root.right = deleteNode(root.right, key);
            return root;
        }
 
        // We reach here when root is the node
        // to be deleted.
 
        // If one of the children is empty
        if (root.left == null) {
            Node temp = root.right;
            return temp;
        } else if (root.right == null) {
            Node temp = root.left;
            return temp;
        }
 
        // If both children exist
        else {
 
            Node succParent = root;
 
            // Find successor
            Node succ = root.right;
            while (succ.left != null) {
                succParent = succ;
                succ = succ.left;
            }
 
            // Delete successor.  Since successor
            // is always left child of its parent
            // we can safely make successor's right
            // right child as left of its parent.
            // If there is no succ, then assign
            // succ.right to succParent.right
            if (succParent != root)
                succParent.left = succ.right;
            else
                succParent.right = succ.right;
 
            // Copy Successor Data to root
            root.key = succ.key;
 
            // Delete Successor and return root
            return root;
        }
    }
 
    // Driver Code
    public static void main(String[] args) {
        BST tree = new BST();
 
        /* Let us create following BST
                  50
               /     \
              30      70
             /  \    /  \
           20   40  60   80 */
        tree.root = tree.insert(tree.root, 50);
        tree.insert(tree.root, 30);
        tree.insert(tree.root, 20);
        tree.insert(tree.root, 40);
        tree.insert(tree.root, 70);
        tree.insert(tree.root, 60);
 
        System.out.print("Original BST: ");
        tree.inorder(tree.root);
 
        System.out.println("\n\nDelete a Leaf Node: 20");
        tree.root = tree.deleteNode(tree.root, 20);
        System.out.print("Modified BST tree after deleting Leaf Node:\n");
        tree.inorder(tree.root);
 
        System.out.println("\n\nDelete Node with single child: 70");
        tree.root = tree.deleteNode(tree.root, 70);
        System.out.print("Modified BST tree after deleting single child Node:\n");
        tree.inorder(tree.root);
 
        System.out.println("\n\nDelete Node with both child: 50");
        tree.root = tree.deleteNode(tree.root, 50);
        System.out.print("Modified BST tree after deleting both child Node:\n");
        tree.inorder(tree.root);
    }
}


Python3




# Python3 program to implement optimized delete in BST.
 
class Node:
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None
 
# A utility function to do inorder traversal of BST
def inorder(root):
    if root is not None:
        inorder(root.left)
        print(root.key, end=' ')
        inorder(root.right)
 
# A utility function to insert a new node with given key in BST
def insert(node, key):
    # If the tree is empty, return a new node
    if node is None:
        return Node(key)
 
    # Otherwise, recur down the tree
    if key < node.key:
        node.left = insert(node.left, key)
    else:
        node.right = insert(node.right, key)
 
    # return the (unchanged) node pointer
    return node
 
# Given a binary search tree and a key, this function
# deletes the key and returns the new root
def deleteNode(root, k):
    # Base case
    if root is None:
        return root
 
    # Recursive calls for ancestors of
    # node to be deleted
    if root.key > k:
        root.left = deleteNode(root.left, k)
        return root
    elif root.key < k:
        root.right = deleteNode(root.right, k)
        return root
 
    # We reach here when root is the node
    # to be deleted.
 
    # If one of the children is empty
    if root.left is None:
        temp = root.right
        del root
        return temp
    elif root.right is None:
        temp = root.left
        del root
        return temp
 
    # If both children exist
    else:
 
        succParent = root
 
        # Find successor
        succ = root.right
        while succ.left is not None:
            succParent = succ
            succ = succ.left
 
        # Delete successor.  Since successor
        # is always left child of its parent
        # we can safely make successor's right
        # right child as left of its parent.
        # If there is no succ, then assign
        # succ.right to succParent.right
        if succParent != root:
            succParent.left = succ.right
        else:
            succParent.right = succ.right
 
        # Copy Successor Data to root
        root.key = succ.key
 
        # Delete Successor and return root
        del succ
        return root
 
# Driver Code
if __name__ == '__main__':
    # Let us create following BST
    #          50
    #       /     \
    #      30      70
    #     /  \    /  \
    #   20   40  60   80
    root = None
    root = insert(root, 50)
    root = insert(root, 30)
    root = insert(root, 20)
    root = insert(root, 40)
    root = insert(root, 70)
    root = insert(root, 60)
 
    print("Original BST: ", end='')
    inorder(root)
 
    print("\n\nDelete a Leaf Node: 20")
    root = deleteNode(root, 20)
    print("Modified BST tree after deleting Leaf Node:")
    inorder(root)
 
    print("\n\nDelete Node with single child: 70")
    root = deleteNode(root, 70)
    print("Modified BST tree after deleting single child Node:")
    inorder(root)
 
    print("\n\nDelete Node with both child: 50")
    root = deleteNode(root, 50)
    print("Modified BST tree after deleting both child Node:")
    inorder(root)


C#




// C# program to implement optimized delete in BST.
using System;
 
class Node {
    public int key;
    public Node left, right;
}
 
class BST {
    // A utility function to create a new BST node
    Node newNode(int item) {
        Node temp = new Node();
        temp.key = item;
        temp.left = temp.right = null;
        return temp;
    }
 
    // A utility function to do inorder traversal of BST
    void inorder(Node root) {
        if (root != null) {
            inorder(root.left);
            Console.Write(root.key + " ");
            inorder(root.right);
        }
    }
 
    /* A utility function to insert a new node with given key in
     * BST */
    Node insert(Node node, int key) {
        /* If the tree is empty, return a new node */
        if (node == null)
            return newNode(key);
 
        /* Otherwise, recur down the tree */
        if (key < node.key)
            node.left = insert(node.left, key);
        else
            node.right = insert(node.right, key);
 
        /* return the (unchanged) node pointer */
        return node;
    }
 
    /* Given a binary search tree and a key, this function
       deletes the key and returns the new root */
    Node deleteNode(Node root, int k) {
        // Base case
        if (root == null)
            return root;
 
        // Recursive calls for ancestors of
        // node to be deleted
        if (root.key > k) {
            root.left = deleteNode(root.left, k);
            return root;
        }
        else if (root.key < k) {
            root.right = deleteNode(root.right, k);
            return root;
        }
 
        // We reach here when root is the node
        // to be deleted.
 
        // If one of the children is empty
        if (root.left == null) {
            Node temp = root.right;
            root = null;
            return temp;
        }
        else if (root.right == null) {
            Node temp = root.left;
            root = null;
            return temp;
        }
 
        // If both children exist
        else {
 
            Node succParent = root;
 
            // Find successor
            Node succ = root.right;
            while (succ.left != null) {
                succParent = succ;
                succ = succ.left;
            }
 
            // Delete successor.  Since successor
            // is always left child of its parent
            // we can safely make successor's right
            // right child as left of its parent.
            // If there is no succ, then assign
            // succ.right to succParent.right
            if (succParent != root)
                succParent.left = succ.right;
            else
                succParent.right = succ.right;
 
            // Copy Successor Data to root
            root.key = succ.key;
 
            // Delete Successor and return root
            succ = null;
            return root;
        }
    }
 
    // Driver Code
    static void Main(string[] args) {
        BST tree = new BST();
 
        /* Let us create following BST
                  50
               /     \
              30      70
             /  \    /  \
           20   40  60   80 */
        Node root = null;
        root = tree.insert(root, 50);
        root = tree.insert(root, 30);
        root = tree.insert(root, 20);
        root = tree.insert(root, 40);
        root = tree.insert(root, 70);
        root = tree.insert(root, 60);
 
        Console.Write("Original BST: ");
        tree.inorder(root);
 
        Console.Write("\n\nDelete a Leaf Node: 20\n");
        root = tree.deleteNode(root, 20);
        Console.Write("Modified BST tree after deleting Leaf Node:\n");
        tree.inorder(root);
 
        Console.Write("\n\nDelete Node with single child: 70\n");
        root = tree.deleteNode(root, 70);
        Console.Write("Modified BST tree after deleting single child Node:\n");
        tree.inorder(root);
 
        Console.Write("\n\nDelete Node with both child: 50\n");
        root = tree.deleteNode(root, 50);
        Console.Write("Modified BST tree after deleting both child Node:\n");
        tree.inorder(root);
    }
}


Javascript




// Javascript program to implement optimized delete in BST.
 
class Node {
  constructor(key) {
    this.key = key;
    this.left = null;
    this.right = null;
  }
}
 
// A utility function to do inorder traversal of BST
function inorder(root) {
  if (root !== null) {
    inorder(root.left);
    console.log(root.key);
    inorder(root.right);
  }
}
 
/* A utility function to insert a new node with given key in
 * BST */
function insert(node, key) {
  /* If the tree is empty, return a new node */
  if (node === null) {
    return new Node(key);
  }
 
  /* Otherwise, recur down the tree */
  if (key < node.key) {
    node.left = insert(node.left, key);
  } else {
    node.right = insert(node.right, key);
  }
 
  /* return the (unchanged) node pointer */
  return node;
}
 
/* Given a binary search tree and a key, this function
   deletes the key and returns the new root */
function deleteNode(root, k) {
  // Base case
  if (root === null) {
    return root;
  }
 
  // Recursive calls for ancestors of
  // node to be deleted
  if (root.key > k) {
    root.left = deleteNode(root.left, k);
    return root;
  } else if (root.key < k) {
    root.right = deleteNode(root.right, k);
    return root;
  }
 
  // We reach here when root is the node
  // to be deleted.
 
  // If one of the children is empty
  if (root.left === null) {
    let temp = root.right;
    delete root;
    return temp;
  } else if (root.right === null) {
    let temp = root.left;
    delete root;
    return temp;
  }
 
  // If both children exist
  else {
    let succParent = root;
 
    // Find successor
    let succ = root.right;
    while (succ.left !== null) {
      succParent = succ;
      succ = succ.left;
    }
 
    // Delete successor.  Since successor
    // is always left child of its parent
    // we can safely make successor's right
    // right child as left of its parent.
    // If there is no succ, then assign
    // succ.right to succParent.right
    if (succParent !== root) {
      succParent.left = succ.right;
    } else {
      succParent.right = succ.right;
    }
 
    // Copy Successor Data to root
    root.key = succ.key;
 
    // Delete Successor and return root
    delete succ;
    return root;
  }
}
 
// Driver Code
(function main() {
  /* Let us create following BST
              50
           /     \
          30      70
         /  \    /  \
       20   40  60   80 */
  let root = null;
  root = insert(root, 50);
  root = insert(root, 30);
  root = insert(root, 20);
  root = insert(root, 40);
  root = insert(root, 70);
  root = insert(root, 60);
 
  console.log("Original BST: ");
  inorder(root);
 
  console.log("\n\nDelete a Leaf Node: 20\n");
  root = deleteNode(root, 20);
  console.log("Modified BST tree after deleting Leaf Node:\n");
  inorder(root);
 
  console.log("\n\nDelete Node with single child: 70\n");
  root = deleteNode(root, 70);
  console.log("Modified BST tree after deleting single child Node:\n");
  inorder(root);
 
  console.log("\n\nDelete Node with both child: 50\n");
  root = deleteNode(root, 50);
  console.log("Modified BST tree after deleting both child Node:\n");
  inorder(root);
})();


Output

Original BST: 20 30 40 50 60 70 

Delete a Leaf Node: 20
Modified BST tree after deleting Leaf Node:
30 40 50 60 70 

Delete Node with single child: 70
Modified BST tree after deleting single child No...



Time Complexity: O(h), where h is the height of the BST. 
Auxiliary Space: O(n).

Related Links: 



Last Updated : 06 Oct, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads