5

How to delete a node with 2 children nodes in a binary tree?

Is there any kind of method to remove it? I googled it. But didn't get clear idea about it. Anybody explain it with diagrammatic representation?

How to delete the node '5' from the this image and what might be the outcome?

Dinesh
  • 16,014
  • 23
  • 80
  • 122

8 Answers8

19

you replace said node with the left most child on its right side, or the right most child on its left side. You then delete the child from the bottom that it was replaced with.

Deleting five could yield either a tree with 3 as its root or 18 as its root, depending on which direction you take.

It looks like you got that image from this site: http://www.algolist.net/Data_structures/Binary_search_tree/Removal

It shows the algorithm you want with images too.

Vici37
  • 518
  • 1
  • 5
  • 9
  • Can I either delete the left most child on its right side, or the right most child on its left side? Doesn't it make any difference? – Lampros Tzanetos Apr 06 '18 at 22:09
4

For deleting a Node there are three scenarios possible..

  1. Node is a leaf node: This is a simple case, figure out whether this node is left or right node of parent and set null as child for the parent for that side.
  2. Node is having one child: Establish a direct link between parent node and child node of this node.
  3. Node has two children: This is little tricky.. the steps involved in this are.
    1. First find the successor (or predecessor) of the this node.
    2. Delete the successor (or predecessor) from the tree.
    3. Replace the node to be deleted with the successor (or predecessor)

Before knowing the concept of deletion, we should understand the concept of successor and predecessors

Successor: In a binary tree successor of a node is the smallest node of the tree that is strictly greater then this node.

There are two possible cases with a node

  • A node has right children: In this case the leftmost child of the right sub-tree will be successor.

  • A node has no children: Go to the parent node and find a node for which this node is part of left sub-tree.

    public Node sucessor(Node node) {
    Node sucessor = null;
    if (node.getRightNode() != null) {
        Node newNode = node.getRightNode();
        while (newNode != null) {
            sucessor = newNode;
            newNode = newNode.getLeftNode();
        }
    } else {
        sucessor = findRightParent(node);
    }
    return sucessor;
    }
    private Node findRightParent(Node node) {
    Node newNode = null;
    if (node.getParentNode() != null) {
        if (node.getParentNode().getLeftNode() == node) {
            newNode = node.getParentNode();
        } else {
            newNode = findRightParent(node.getParentNode());
        }
    }
    return newNode;
    }
    

Now the deletion logic

     public void deleteNode(Node node) {
    // Node is a leaf node //
    if( node.getLeftNode() == null && node.getRightNode() == null){
        if(isRightNode(node.getParentNode(), node)){
            node.getParentNode().setRightNode(null);
        }else{
            node.getParentNode().setLeftNode(null);
        }
        // Only left child is there//
    }else if( node.getLeftNode() != null && node.getRightNode() == null){
        if(isRightNode(node.getParentNode(), node)){
            node.getParentNode().setRightNode(node.getLeftNode());
        }else{
            node.getParentNode().setLeftNode(node.getLeftNode());
        }
        // Only Right child is there //
    }else if( node.getLeftNode() == null && node.getRightNode() != null){
        if( isRightNode(node.getParentNode(), node)){
            node.getParentNode().setRightNode(node.getRightNode());
        }else{
            node.getParentNode().setLeftNode(node.getRightNode());
        }
        // Both Left and Right children are their//
    }else{
        Node psNode = predessor(node);
        deleteNode(psNode);
        psNode.setParentNode(node.getParentNode());
        psNode.setLeftNode(node.getLeftNode());
        psNode.setRightNode(node.getRightNode());
        if( isRightNode(node.getParentNode(), node)){
            node.getParentNode().setRightNode(psNode);
        }else{
            node.getParentNode().setLeftNode(psNode);
        }
    }

    }

Solution is taken from http://coder2design.com/binary-tree/

Also they have explained the flow of traversal and insertion with full source code.

ebram khalil
  • 8,252
  • 7
  • 42
  • 60
Jatinder Pal
  • 719
  • 8
  • 3
2

A simple and easy solution:

            Node* findMaxNode(Node* root)
            {
                if(root->right == NULL) return root;
                findMaxNode(root->right);
            }


            Node* DeleteNodeInBST(Node* root,int data)
            {
                //base case when not found or found then recursion breaks

                if(root == NULL) return root;
                else if(root->data > data) root->left = DeleteNodeInBST(root->left, data);
                else if(root->data < data) root->right = DeleteNodeInBST(root->right, data);
                else
                {
                    //when the node to be deleted is found
                    //Four possibilities

                    //case1: When the node to be deleted has no children
                    if(root->left == NULL && root->right == NULL)
                    {
                        delete root;
                        root = NULL;
                    }
                    //case2: When the node to be deleted has ONLY LEFT child
                    else if(root->right == NULL)
                    {
                        Node* temp = root;
                        root = root->left;
                        delete temp;
                    }
                    //case3: When the node to be deleted has ONLY RIGHT child
                    else if(root->left == NULL)
                    {
                        Node* temp = root;
                        root = root->right;
                        delete temp;
                    }
                    //case4: When the node to be deleted has TWO children
                    else
                    {
                        Node* maxNode = findMaxNode(root->left);//finding the maximum in LEFT sub-tree
                        root->data = maxNode->data; //Overwriting the root node with MAX-LEFT
                        root->left = DeleteNodeInBST(root->left, maxNode->data);//deleted the MAX-LEFT node
                    }
                    return root;
                }

            }
1

Wikipedia article gives a good description of BST:

http://en.wikipedia.org/wiki/Binary_search_tree

When you delete a node with 2 children, 5 in your case, you can replace the deleted node with minimum value node from the right subtree, or maximum value node from the left subtree.

Asterisk
  • 3,534
  • 2
  • 34
  • 53
  • Can I either delete the left most child on its right side, or the right most child on its left side? Doesn't it make any difference? – Lampros Tzanetos Apr 06 '18 at 22:16
0

Algorithm :

->Find the node which need to delete (assume data is given)
->Find the deepest node of tree
->Replace deepest node's data with the node to be deleted
->Delete the deepest node

Java implementation :

 public static void deleteTheNode(BTNode root, int data) {
    BTNode nodeToDelete = findTheNode(root, data);

    if (nodeToDelete == null) {
        System.out.println("Node Does not exists in Binary Tree");
        return;
    }
    BTNode deepestNode = findDepestNodeOfBinaryTree(root);
    nodeToDelete.setData(deepestNode.getData());
    _deleteTheNode(root, deepestNode);

}

private static void _deleteTheNode(BTNode root, BTNode node) {
    Queue<BTNode> q = new LinkedList<>();
    q.offer(root);

    while (!q.isEmpty()) {
        BTNode temp = q.poll();
        if (temp.getLeft() == node) {
            temp.setLeft(null);
            node = null;
            break;
        } else if (temp.getRight() == node) {
            temp.setRight(null);
            node = null;
            break;
        }
        if (temp.getLeft() != null) {
            q.offer(temp.getLeft());
        }
        if (temp.getRight() != null) {
            q.offer(temp.getRight());
        }
    }
}
//Find the deepest nodeof the binary tree
public static BTNode findDepestNodeOfBinaryTree(BTNode root) {
    int depth = 0;
    BTNode deepetNode = root;
    Stack<BTNode> nodes = new Stack<>();
    Stack<BTNode> path = new Stack<>();

    if (root == null) {
        return null;
    }
    nodes.push(root);
    while (!nodes.empty()) {
        BTNode node = nodes.peek();
        if (!path.empty() && node == path.peek()) {
            if (path.size() > depth) {
                depth = path.size() - 1;
                deepetNode = node;
            }
            path.pop();
            nodes.pop();
        } else {
            path.push(node);
            if (node.getRight() != null) {
                nodes.push(node.getRight());
            }
            if (node.getLeft() != null) {
                nodes.push(node.getLeft());
            }
        }
    }

    return deepetNode;
}
Chandan Rajput
  • 441
  • 5
  • 18
0

Find the inorder successor of the node to be deleted. Then copy the content of inorder successor of the node and delete the inorder successor. (You can also use inorder predecessor instead of inorder successor)

-1

A simple deletion of a node that has 2 children is to relabel parent’s child of deleted node with its successor.

Ivan Voroshilin
  • 5,233
  • 3
  • 32
  • 61
-1

You can't use the left most node of the right sub tree. Say you have a tree and the left most node of the right sub tree is 15, but the parent of 15 is also 15, so replacing the node to be deleted with the left most node on right sub tree can give you a node of equal value in the right sub tree. The 15 would become new root of that sub tree in my example and then there would be another 15 to the right of the root.

Andrew
  • 1