Deleting node from generic tree - java

I can't write correctly function that deletes one node from tree. If this node has children, they should move one level higher. Children of deleted element will have parent of deleted elem,ancestors will they on they places, but one level higher. How can I do it right?
import java.util.ArrayList;
import java.util.List;
public class Node<T> {
private T value;
private final List<Node<T>> listOfChildren;
private Node<T> parent;
public Node(){
super();
listOfChildren = new ArrayList<>();
}
public Node(T value){
this();
setValue(value);
}
public T getValue() {
return value;
}
public void setParent(Node<T> parent) {
this.parent = parent;
}
public List<Node<T>> getListOfChildren() {
return listOfChildren;
}
public void setValue(T value) {
this.value = value;
}
public int getNumberOfChildren() {
return listOfChildren.size();
}
public void addChildren(Node<T> child) {
parent = this;
listOfChildren.add(child);
}
public void removeChildAt(int index) {
if (index > listOfChildren.size()-1){
throw new IndexOutOfBoundsException( "This index is too big");
}
else {
Node<T> element = this.listOfChildren.get(index);
if (element.listOfChildren.size() > 0) {
// function...
}
listOfChildren.remove(index);
}
}
}
I think that writing dfs or bfs to walk through the tree is not the best way to realize this function. What is the best way to realize this function?

Children of deleted element will keep their descendants, so no walk through required
public void removeChildAt(int index) throws IndexOutOfBoundsException {
if (listOfChildren != null) {
Node<T> element = this.listOfChildren.get(index);
if (element.listOfChildren.size() > 0) {
this.listOfChildren.addAll(element.listOfChildren);
//element.listOfChildren.forEach(child -> child.setParent(this)); but you have no backward reference to parent
}
listOfChildren.remove(index);
}
else {
System.out.println("No children from this node");
}
}

Related

Tree Comparison Algorithm in Java

I am looking for an algorithm to compare two trees.
I have this class in Java
public class TreeNodeDSP {
TreeNodeDSP parent;
List<TreeNodeDSP> children;
NodeDSP value;
public TreeNodeDSP(TreeNodeDSP parent) {
this.parent = parent;
children = new ArrayList<>();
}
public TreeNodeDSP(TreeNodeDSP parent, NodeDSP value) {
this.parent = parent;
children = new ArrayList<>();
this.value = value;
}
public void addChild(TreeNodeDSP node) {
if (node != null && node.getValue() != null) {
if (children.stream().noneMatch(child -> Objects.equals(child.getValue(), node.getValue()))) {
children.add(node);
}
}
}
public TreeNodeDSP getParent() {
return parent;
}
public void cleanChildren() {
children = new ArrayList<>();
}
public int getChildrenCount() {
return children.size();
}
public TreeNodeDSP getChildrenAt(int position) {
if (children.size() > position && position > -1) {
return children.get(position);
}
return null;
}
public List<TreeNodeDSP> getChildren() {
return children;
}
public NodeDSP getValue() {
return value;
}
public boolean isLeaf() {
return children.isEmpty();
}
}
I think the code of NodeDSP class is not needed.
Now, I have an algorithm to populate my Tree (TreeNodeDSP) and facing problem performing operations based on Automatically populate Tree (calculating some conditions),
I populate manually my Tree and works.
I need to discover what is the difference in my Tree (manually Populated, and Automatically) in its nodes (internally), not only says are different Trees. When some node/leaf is different I need to print its contents.
But, I don't know how to begin with the comparison Algorithm.

When I pass the Node variable that is "top" inside the node objects ? does it help it to point the previous data?

I am writing a code to practice some linked list example with basics but came across a problem when in linked list class in voidadd method what does it means when I pass the Node variable that is "top" inside the node objects ? does it help it to point the previous data? i have indicated the part that refers to my question
public class Node
{
private int data;
private Node nextNode;
public Node(int dataP , Node nextNodeP)
{
data = dataP;nextNode = nextNodeP;
}
public int getData()
{
return data;
}
public Node getNextNode()
{
return nextNode;
}
public void setData(int newData) //to replace the value of some notes [12| ] --> [120| ]
{
data = newData;
}
public void setNext(Node newNextNode) // pointing to top ---> [120| ] ---> [last | null]
{
nextNode = newNextNode;
}
}
public class LinkedList {
private Node top;
private int size;
public LinkedList() {
top = null;
size = 0;
}
public int getSize() {
return size;
}
public void addNode(int newData) {
Node temp = new Node(newData, top); //question
top = temp; //points to the same
size++;
}
}
Define a node at its own class.
Here is a simple example :
public class LinkedList {
private Node first,last;
private int size ;
//adds node as last. not null safe
public void addNode(Node node) {
if(first == null) {
node.setParent(null);
first = node;
last = node;
}else {
node.setParent(last);
last = node;
}
size++;
}
public Node getFirst() {return first;}
public Node getLast() { return last; }
public int getSize() {return size;}
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.addNode(new Node(0,null));
list.addNode(new Node(1,null));
list.addNode(new Node(2,null));
list.addNode(new Node(3,null));
Node node = list.getLast();
System.out.println("list has "+ list.size + " nodes:");
while(node != null) {
System.out.println(node);
node = node.getParent();
}
}
}
class Node{
private int data;
private Node parent;
Node(int nodeData, Node parent) {
data = nodeData;
this.parent = parent;
}
public int getData() { return data;}
public void setData(int data) { this.data = data; }
public Node getParent() {return parent; }
public void setParent(Node parent) {this.parent = parent;}
#Override
public String toString() {return "Node "+getData() +" parent:"+ getParent();}
}

Is it possible to link multiple nodes to a single node?

I'm trying to make a tree structure based on the linked list. Since linked list can only directly point to the next node(For singly linked list), I would like to modify the concept of the linked list. Is it possible to point at the one node from multiple nodes?
Here is an image in drawing
I think the following would work:
class Node {
Node sibling;
Node child;
Object item;
}
sibling will point to next Node at parallel level, child points to Node on lower level.
See below my implementation:
package treeTest;
public class Node {
private Node left;
private Node right;
private String data;
public Node(String data) {
this.data = data;
left = null;
right = null;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
package treeTest;
public class Tree {
private Node root;
public Tree() {
root = null;
}
public void insert(String data) {
root = insert(root, data);
}
private Node insert(Node node, String data) {
if(node == null) {
// Then create tree
node = new Node(data);
} else {
if(data.compareTo(node.getData()) <= 0) {
node.setLeft( insert(node.getLeft(), data));
} else {
node.setRight(insert(node.getRight(), data));
}
}
return node;
}
}
package treeTest;
import java.util.Scanner;
public class TestTree {
public static void main(String[] args) {
// TODO Auto-generated method stub
Tree tree = new Tree();
tree.insert("Hurricane");
// Second level
tree.insert("Cat1");
tree.insert("Cat2");
tree.insert("Cat3");
}
}
For more details checkout this Java Program to Implement a Binary Search Tree using Linked Lists

How to Traverse a N-Ary Tree

My Tree/Node Class:
import java.util.ArrayList;
import java.util.List;
public class Node<T> {
private T data;
private List<Node<T>> children;
private Node<T> parent;
public Node(T data) {
this.data = data;
this.children = new ArrayList<Node<T>>();
}
public Node(Node<T> node) {
this.data = (T) node.getData();
children = new ArrayList<Node<T>>();
}
public void addChild(Node<T> child) {
child.setParent(this);
children.add(child);
}
public T getData() {
return this.data;
}
public void setData(T data) {
this.data = data;
}
public Node<T> getParent() {
return this.parent;
}
public void setParent(Node<T> parent) {
this.parent = parent;
}
public List<Node<T>> getChildren() {
return this.children;
}
}
I know how to traverse a Binary Tree, but traversing a N-Ary seems much more tricky.
How would I go about traversing through this tree. I want a counter whilst I traverse the tree as to number/count each node in the tree.
Then at a specific count, I can stop and return the node at that count (perhaps remove that subtree or add a subtree at that position).
The simplest way is to implement a Visitor pattern like this:
public interface Visitor<T> {
// returns true if visiting should be cancelled at this point
boolean accept(Node<T> node);
}
public class Node<T> {
...
// returns true if visiting was cancelled
public boolean visit(Visitor<T> visitor) {
if(visitor.accept(this))
return true;
for(Node<T> child : children) {
if(child.visit(visitor))
return true;
}
return false;
}
}
Now you can use it like this:
treeRoot.visit(new Visitor<Type>() {
public boolean accept(Node<Type> node) {
System.out.println("Visiting node "+node);
return false;
}
});
Or for your particular task:
class CountVisitor<T> implements Visitor<T> {
int limit;
Node<T> node;
public CountVisitor(int limit) {
this.limit = limit;
}
public boolean accept(Node<T> node) {
if(--limit == 0) {
this.node = node;
return true;
}
return false;
}
public Node<T> getNode() {
return node;
}
}
CountVisitor<T> visitor = new CountVisitor<>(10);
if(treeRoot.visit(visitor)) {
System.out.println("Node#10 is "+visitor.getNode());
} else {
System.out.println("Tree has less than 10 nodes");
}

Binary search tree implementation in java with traversal

I have implemented a Binary search tree with insert and traversal method but am not getting correct output for PreOrder and Postorder ,am getting inOrder in correct order. Could some one please tell me where am wrong.
I tried the same example on paper but the PreOrder and PostOrder is not same.
Here is my Code
Node Class
package com.BSTTest;
public class Node implements Comparable<Node> {
private int data;
private Node leftChild;
private Node rightChild;
public Node(int data) {
this(data, null, null);
}
public Node(int data, Node leftChild, Node rightChild) {
this.data = data;
this.leftChild = leftChild;
this.rightChild = rightChild;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getLeftChild() {
return leftChild;
}
public void setLeftChild(Node leftChild) {
this.leftChild = leftChild;
}
public Node getRightChild() {
return rightChild;
}
public void setRightChild(Node rightChild) {
this.rightChild = rightChild;
}
public int compareTo(Node o) {
return Integer.compare(this.data, o.getData());
}
}
Tree Class
package com.BSTTest;
import com.BSTTest.Node;
public class Tree {
private Node root = null;
public Node getRoot() {
return root;
}
//Inserting data**strong text**
public void insertData(int data) {
Node node = new Node(data, null, null);
if (root == null) {
root = node;
} else {
insert(node, root);
}
}
//Helper method for insert
private void insert(Node node, Node currNode) {
if (node.compareTo(currNode) < 0) {
if (currNode.getLeftChild() == null) {
currNode.setLeftChild(node);
} else {
insert(node, currNode.getLeftChild());
}
} else {
if (currNode.getRightChild() == null) {
currNode.setRightChild(node);
} else {
insert(node, currNode.getRightChild());
}
}
}
public void printInorder() {
printInOrderRec(root);
System.out.println("");
}
//Helper method to recursively print the contents in an inorder way
private void printInOrderRec(Node currRoot) {
if (currRoot == null) {
return;
}
printInOrderRec(currRoot.getLeftChild());
System.out.print(currRoot.getData() + ", ");
printInOrderRec(currRoot.getRightChild());
}
public void printPreorder() {
printPreOrderRec(root);
System.out.println("");
}
// Helper method for PreOrder Traversal recursively
private void printPreOrderRec(Node currRoot) {
if (currRoot == null) {
return;
}
System.out.print(currRoot.getData() + ", ");
printPreOrderRec(currRoot.getLeftChild());
printPreOrderRec(currRoot.getRightChild());
}
public void printPostorder() {
printPostOrderRec(root);
System.out.println("");
}
/**
* Helper method for PostOrder method to recursively print the content
*/
private void printPostOrderRec(Node currRoot) {
if (currRoot == null) {
return;
}
printPostOrderRec(currRoot.getLeftChild());
printPostOrderRec(currRoot.getRightChild());
System.out.print(currRoot.getData() + ", ");
}
//Main Mthod
public static void main(String[] args) {
Tree obj = new Tree();
//Inserting data
obj.insertData(3);
obj.insertData(5);
obj.insertData(6);
obj.insertData(2);
obj.insertData(4);
obj.insertData(1);
obj.insertData(0);
//printing content in Inorder way
System.out.println("Inorder traversal");
obj.printInorder();
//printing content in Inorder way
System.out.println("Preorder Traversal");
obj.printPreorder();
//printing content in Inorder way
System.out.println("Postorder Traversal");
obj.printPostorder();
}
}
Look my friend,your code is absolutely fine as the outputs you mentioned are absolutely correct.
I think you have not understood the concept of Binary Search Tree correctly.
You are right,3 is root node but you wrong in saying that 1 is its left child.
The first value that appears after 3 and that is smaller than 3 is 2,therefore 2 is left child of 3 and not 1
Refer to Cormenn book if still there is confusion.

Categories

Resources