Delete nodes from a Tree in Java

In this tutorial we will see how to delete nodes from a Tree. In my last tutorial create and traverse java tree tutorial I showed how to create a tree and then we also looked at an example of traversing the tree.

Reference Tree

The image below shows the Tree that we will use in this tutorial. We will do all the operations on this tree.
example tree
Example tree

Node deletion

When deleting a node we will look at two cases;
1. Deletion of any nodes except the root node,
2. Deletion of root node.

 

Deletion of any node except the root Node

Here are the steps we will follow:
1. Delete the current node from the list of children of current nodes parent.
2. Assign the children of this node to the parent of this node. So if we have to delete “Node 12” then we will make “Node 121” and “Node 122” as the children of  “Node 1”.
3. The parent reference of the children will also be updated to the parent of this node.
4. The children are added at the same index as the deleted node.
So here is the function that does the deletion of a node.

public void deleteNode(){
 if (parent != null) {
  int index = this.parent.getChildren().indexOf(this);
  this.parent.getChildren().remove(this);
  for(Node each:getChildren()){
   each.setParent(this.parent);
  }
  this.parent.getChildren().addAll(index,this.getChildren());
 } 
 this.getChildren().clear();
}

 

Deletion of root Node



Deleting the root node is special as the root node has no parents to which the children of the root node could be assigned. So in this particular tutorial we will use the first child of the root node as the new root for the tree.
Here is the code for deletion of the root node:

public Node  deleteRootNode() {
 if (parent != null) {
  throw new IllegalStateException("delete root node can be only called on the root node of tree");
 }
 Node newParent = null;
 if(!getChildren().isEmpty()){
  newParent = getChildren().get(0);
  newParent.setParent(null);
  getChildren().remove(0);
  for (Node each:getChildren()) {
   each.setParent(newParent);
  }
  newParent.getChildren().addAll(getChildren());
 }
 this.getChildren().clear();
 return newParent;
}

Examples

Now that we know how to do the deletions let us look at an example that create a Tree first and then does the deletion of the nodes.
Node.java : Represents tree node that has both the methods, one for deletion of nodes and one for the deletion of other nodes.

package com.programtak.tree.tutorial;

import java.util.ArrayList;
import java.util.List;

public class Node {
 private String id;
 private final List<Node> children = new ArrayList<>();
 private Node parent;

 public Node getRoot() {
  if (getParent() == null) {
   return this;
  }
  return getParent().getRoot();
 }

 public Node deleteRootNode() {
  if (parent != null) {
   throw new IllegalStateException("delete root node can be only called on the root node of tree");
  }
  Node newParent = null;
  if (!getChildren().isEmpty()) {
   newParent = getChildren().get(0);
   newParent.setParent(null);
   getChildren().remove(0);
   for (Node each : getChildren()) {
    each.setParent(newParent);
   }
   newParent.getChildren().addAll(getChildren());
  }
  this.getChildren().clear();
  return newParent;
 }

 public void deleteNode() {
  if (parent != null) {
   int index = this.parent.getChildren().indexOf(this);
   this.parent.getChildren().remove(this);
   for (Node each : getChildren()) {
    each.setParent(this.parent);
   }
   this.parent.getChildren().addAll(index, this.getChildren());
  }
  this.getChildren().clear();
 }

 public Node(Node parent) {
  this.setParent(parent);
 }

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

 public List<Node> getChildren() {
  return children;
 }

 public Node getParent() {
  return parent;
 }

 public void setParent(Node parent) {
  this.parent = parent;
 }

 @Override
 public String toString() {
  return "Node[id:" + getId() + "]";
 }

}

 

Example code of deletion of a list of Nodes 

Nodes to be deleted underlined red
Nodes to be deleted underlined red

 After deletion the tree will look as below:

nodes deletd
Tree after deletion of nodes

As shown in the above diagram, let us delete a list of nodes that are underlined with red line from the Tree. Here is the test class that creates above Tree and deletes a list of nodes from the tree

package com.programtak.tree.tutorial;

import java.util.Arrays;
import java.util.List;

public class RemoveListNodesFromTree {

 public static void main(String[] args) {
  Node treeRootNode = new Node(null);
  treeRootNode.setId("root");
  // add child to root node 
  Node childNode1= addChild(treeRootNode, "child-1");
  // add child to the child node created above
  addChild(childNode1, "child-11");
  
  Node childNode12 = addChild(childNode1, "child-12");
  addChild(childNode12, "child-121");
  addChild(childNode12, "child-122");
  
  
  // add child to root node
  Node child2 = addChild(treeRootNode, "child-2");
  // add child to the child node created above
  addChild(child2, "child-21");
  System.out.println("<------- Tree before deletion of nodes --->");
  printTree(treeRootNode, " ");
  
  List<Node> toBeDeleted = Arrays.asList(childNode1,childNode12, child2);
  System.out.println("nRemove children:" + toBeDeleted);
  removeSelectedNodes(treeRootNode,  toBeDeleted, 0);
  System.out.println("n<------- Tree after  deletion of nodes --->");
  printTree(treeRootNode, " ");
  

 }

 private static Node addChild(Node parent, String id) {
   Node node = new Node(parent);
   node.setId(id);
   parent.getChildren().add(node);
   
   return node;
 }

 private static void printTree(Node node, String appender) {
  System.out.println(appender + node);
  for (Node each : node.getChildren()) {
   printTree(each, appender + appender);
  }
 }
 
 
 private static void removeSelectedNodes(Node node,
   List<Node> toBedeletedNodes, int startFrom) {
  
  for (int i = startFrom; i < node.getChildren().size(); i++) {
   Node each = node.getChildren().get(i);
   if (toBedeletedNodes.contains(each)) {
    each.deleteNode();
    removeSelectedNodes(node, toBedeletedNodes, i);
    break;

   }
   removeSelectedNodes(each ,toBedeletedNodes, 0);
  }
 }
 
}

And here is the output that shows the deletion of nodes
<------- Tree before deletion of nodes --->
 Node[id:root]
  Node[id:child-1]
    Node[id:child-11]
    Node[id:child-12]
        Node[id:child-121]
        Node[id:child-122]
  Node[id:child-2]
    Node[id:child-21]

Remove children:[Node[id:child-1], Node[id:child-12], Node[id:child-2]]

<------- Tree after  deletion of nodes --->
 Node[id:root]
  Node[id:child-11]
  Node[id:child-121]
  Node[id:child-122]
  Node[id:child-21]

Example code of deletion of root node


After node deletion image
After node deletion



In the  below example we will see how to delete the root node. In the diagram above you can see how the tree will look like once the root node is deleted.

package com.programtak.tree.tutorial;

import java.util.List;

public class RemoveRootNodeTree {

 public static void main(String[] args) {
  Node treeRootNode = new Node(null);
  treeRootNode.setId("root");
  // add child to root node 
  Node childNode1= addChild(treeRootNode, "child-1");
  // add child to the child node created above
  addChild(childNode1, "child-11");
  
  Node childNode12 = addChild(childNode1, "child-12");
  addChild(childNode12, "child-121");
  addChild(childNode12, "child-122");
  
  
  // add child to root node
  Node child2 = addChild(treeRootNode, "child-2");
  // add child to the child node created above
  addChild(child2, "child-21");
  
  System.out.println("<------- Tree before deletion of root node --->");
  printTree(treeRootNode, " ");
  
  System.out.println("nRemove root node :" + treeRootNode);
  Node newRootNode = treeRootNode.deleteRootNode();
  System.out.println("n<------- Tree after  deletion of root node --->");
  printTree(newRootNode, " ");
  
 }

 private static Node addChild(Node parent, String id) {
   Node node = new Node(parent);
   node.setId(id);
   parent.getChildren().add(node);
   
   return node;
 }

 private static void printTree(Node node, String appender) {
  System.out.println(appender + node);
  for (Node each : node.getChildren()) {
   printTree(each, appender + appender);
  }
 }
   
}

Now let us look at the output, which shows the deletion of root node

<------- Tree before deletion of root node --->
 Node[id:root]
  Node[id:child-1]
    Node[id:child-11]
    Node[id:child-12]
        Node[id:child-121]
        Node[id:child-122]
  Node[id:child-2]
    Node[id:child-21]

Remove root node :Node[id:root]

<------- Tree after  deletion of root node --->
 Node[id:child-1]
  Node[id:child-11]
  Node[id:child-12]
    Node[id:child-121]
    Node[id:child-122]
  Node[id:child-2]
    Node[id:child-21]

Thanks for reading this article. Please drop your suggestions and comments below.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.