I'm trying to create binary tree by following example 1 where tree is made without getters and setters. I would like to create it with geeters and setters but I'm stuck on line with recursion. How can I call recursion function with/inside setter? Here is the code..
p.s. Tree class pastebin
public class TreeF {
Tree root;
public void insert(int value) {
if (root==null) {
root = new Tree(value);
return;
}
Tree current = root;
if (value < current.getData() ) {
if (current.getLeft()==null) {
current.setLeft(new Tree (value));
}else {
// call insert method inside current.left object [currrent.left(insert(value))]
current=current.getLeft();
insert (value);
}
}
else {
if (current.getRight()==null) {
current.setRight(new Tree (value));
}else {
current=current.getRight();
insert (value);
}
}
}
}
Change insert(value) to current.insert(value)
To implement recursion, you need to change a parameter(or multiple) so you can go to the stopping condition after some recursive calls.
In your code, you called the method insert that was part of the same object. And not its left/right subtree. In other words, the recursion never ends, because you don't visit the child subtrees.
public class Tree {
private int data;
private Tree left;
private Tree right;
public Tree (int data) {
this.data=data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Tree getLeft() {
return left;
}
public void setLeft(Tree left) {
this.left = left;
}
public Tree getRight() {
return right;
}
public void setRight(Tree right) {
this.right = right;
}
public void insert(int value) {
if (value < getData()) {
if (getLeft() == null) {
setLeft(new Tree(value));
} else {
getLeft().insert(value);
}
} else {
if (getRight() == null) {
setRight(new Tree(value));
} else {
getLeft().insert(value);
}
}
}
}
You do not need a current field or a root. Here's your insert method greatly simplified to demonstrate.
public class Tree {
final int data;
Tree left;
Tree right;
public Tree(int value) {
data = value;
}
public void insert(int value) {
if (value < data) {
if (left == null) {
left = new Tree(value);
} else {
left.insert(value);
}
} else {
if (right == null) {
right = new Tree(value);
} else {
right.insert(value);
}
}
}
}
Related
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");
}
}
Here is the Node class:
public class BSTNode<T extends Comparable<? super T>> {
private T data;
private BSTNode<T> left;
private BSTNode<T> right;
BSTNode(T data) {
this.data = data;
}
T getData() {
return data;
}
BSTNode<T> getLeft() {
return left;
}
BSTNode<T> getRight() {
return right;
}
void setData(T data) {
this.data = data;
}
void setLeft(BSTNode<T> left) {
this.left = left;
}
void setRight(BSTNode<T> right) {
this.right = right;
}
}
Here is my BST class with main driver method:
import java.util.NoSuchElementException;
public class BST<T extends Comparable<? super T>> {
private BSTNode<T> root;
private int size;
BST() {
root = null;
}
public void add(T data) {
if (data == null) {
throw new IllegalArgumentException("Error: Data can't be null");
}
root = rAdd(root, data);
}
private BSTNode<T> rAdd(BSTNode<T> current, T data) {
if (current == null) {
size++;
return new BSTNode<T>(data);
} else if (data.compareTo(current.getData()) < 0) {
current.setLeft(rAdd(current.getLeft(), data));
} else if (data.compareTo(current.getData()) > 0) {
current.setRight(rAdd(current.getRight(), data));
}
return current;
}
public T remove(T data) {
if (data == null) {
throw new IllegalArgumentException("Error: data can't be null");
}
BSTNode<T> dummy = new BSTNode<>(null);
root = rRemove(root, data, dummy);
return dummy.getData();
}
private BSTNode<T> rRemove(BSTNode<T> current, T data, BSTNode<T> dummy) {
if (current == null) {
throw new NoSuchElementException("Error: Data not present");
} else if (data.compareTo(current.getData()) < 0) {
current.setLeft(rRemove(current.getLeft(), data, dummy));
} else if (data.compareTo(current.getData()) > 0) {
current.setRight(rRemove(current.getRight(), data, dummy));
} else {
System.out.println("Data found ... ");
dummy.setData(current.getData());
size--;
if (current.getRight() == null && current.getLeft() == null) {
if (current.equals(root)) {
this.root = null;
}
return null;
} else if (current.getLeft() != null) {
return current.getLeft();
} else if (current.getRight() != null) {
return current.getRight();
} else {
BSTNode<T> dummy2 = new BSTNode<>(null);
current.setRight(removeSuccessor(current.getRight(), dummy2));
current.setData(dummy2.getData());
}
}
return current;
}
private BSTNode<T> removeSuccessor(BSTNode<T> current, BSTNode<T> dummy) {
if (current.getLeft() == null) {
dummy.setData(current.getData());
return current.getRight();
} else {
current.setLeft(removeSuccessor(current.getLeft(), dummy));
}
}
public List<T> inorder(BSTNode<T> root) {
ArrayList<T> inorderContents = new ArrayList<T>();
if (root == null) {
return inorderContents;
}
inorderR(inorderContents, root);
return inorderContents;
}
private void inorderR(ArrayList<T> inorderContents, BSTNode<T> current) {
if (current == null) {
return;
}
inorderR(inorderContents, current.getLeft());
inorderContents.add(current.getData());
inorderR(inorderContents, current.getRight());
}
public BSTNode<T> getRoot() {
// DO NOT MODIFY THIS METHOD!
return root;
}
public int size() {
// DO NOT MODIFY THIS METHOD!
return size;
}
public static void main(String[] args) {
BST bst3 = new BST<>();
bst3.add(1);
bst3.add(0);
bst3.add(5);
bst3.add(4);
bst3.add(2);
bst3.add(3);
System.out.println(bst3.inorder(bst3.getRoot() ));
bst3.remove(1);
System.out.println(bst3.inorder(bst3.getRoot() ));
}
}
My IDE (IntelliJ) says I am missing a return statement for my removeSuccessor(BSTNode current, BSTNode dummy) method but I expected it to recurse to the base case reinforcing the unchanged nodes.
As a result when I try and remove from a two child node it returns zero although the one child and zero child cases work .
Please can someone tell me what is wrong with my two child node remove case? Thanks, Sperling.
First, you need to modify the if-else by changing the conditions:
if (current.getLeft() != null && current.getRight() == null) {
return current.getLeft();
} else if (current.getRight() != null && current.getLeft() == null) {
return current.getRight();
}
instead of the same without the 2nd arguments of && in the rRemove() method.
Then, use this:
private BSTNode<T> removeSuccessor(BSTNode<T> current, BSTNode<T> dummy) {
if (current.getLeft() == null) {
dummy.setData(current.getData());
return current.getRight();
} else {
current.setLeft(removeSuccessor(current.getLeft(), dummy));
return current;
}
}
Meaning of this method is as follows: delete the lowest value in the tree and return new root, as well as remember the value using dummy.
If we get nothing to the left, it's trivial - we delete current node, return getRight() and set a value to dummy.
On the other hand, if we get something to the left then we know that our current node will be the root, but before we return it we need to remove the lowest entry to the left, and so we use the function recursively, also setting current.left to be it's return value to properly transform the tree. We pass dummy so that it can get a value when the first case occurs, and then it's communicated to the highest call (inside the first function).
It's also possible to do it without recursion:
private BSTNode<T> removeSuccessor2(BSTNode<T> current, BSTNode<T> dummy) {
BSTNode<T> root = current;
BSTNode<T> prev = null;
while(current.getLeft() != null) {
prev = current;
current = current.getLeft();
}
/* current.getLeft == null */
//we will delete current
if (prev == null) { //no loop iterations -- current is the root
dummy.setData(current.getData());
return(current.getRight());
}
else {//some iterations passed, prev.getLeft() == curret
dummy.setData(current.getData());
prev.setLeft(current.getRight());
return root;
}
}
With dummy we return the value, the rest is transforming the tree.
Note: It doesn't work in my version for current == null. You should be able to modify it easily, though. Also, for clarity I didn't pull the dummy.setData... before if...else etc. Modify it as you wish!
Trying to search the binary search tree but there seems I cannot figure out why the there statement is not working, the method calls for the input of a String, but it says that a Node is required. Any suggestions how to fix this?
Here is the Node Class:
public class Node
{
String key;
Node left, right;
public Node(String entry)
{
key = entry;
left = right = null;
}
public Node getLeft()
{
return left;
}
public Node getRight()
{
return right;
}
public String getKey(String entry)
{
if(this.key.equals(key))
{
return key;
}
if(entry.compareTo(this.key) < 0)
{
return left == null ? null : left.getKey(entry);
}
else
{
return right == null ? null : right.getKey(entry);
}
}
public void setLeft(Node left)
{
this.left = left;
}
public void setRight(Node right)
{
this.right = right;
}
}
Here is my Binary Search Tree:
public class BinarySearchTree
{
Node root;
public BinarySearchTree()
{
root = null;
}
public void insert(String key)
{
root = insertRec(root, key);
}
public Node insertRec(Node root, String key)
{
if(root == null)
{
root = new Node(key);
return root;
}
if(key.compareTo(root.toString()) == -1)
{
root.setLeft(insertRec(root.getLeft(), key));
}
else if(key.compareTo(root.toString()) == 1)
{
root.setRight(insertRec(root.getRight(), key));
}
return root;
}
public Node search(String key)
{
return root == null ? null : root.getKey(key);
}
public void printPostOrder(Node node)
{
if(node == null)
return;
printPostOrder(root.getLeft());
printPostOrder(node.getRight());
System.out.print(node.getKey() + ", ");
}
public void printInOrder(Node node)
{
if(node == null)
return;
printInOrder(node.getLeft());
System.out.print(node.getKey() + ", ");
printInOrder(node.getRight());
}
public void printPreOrder(Node node)
{
if(node == null)
return;
System.out.print(node.getKey() + ", ");
printPreOrder(node.getLeft());
printPreOrder(node.getRight());
}
public void printPostOrder()
{
printPostOrder(root);
}
public void printInOrder()
{
printInOrder(root);
}
public void printPreOrder()
{
printPreOrder(root);
}
}
Any and all help is much appreciated if you need more information please let me know.
whats up ?
your code is wrong in the class node in method getKey change your return String to Node and your if equals and return to this.
Ex:.
public Node getKey(String entry)
{
if(this.key.equals(entry))
{
return this;
}
}
if you change this your code work.
Full class BinarySearchTree tested ok
public class BinarySearchTree
{
Node root;
public BinarySearchTree()
{
root = null;
}
public void insert(String key)
{
root = insertRec(root, key);
}
public Node insertRec(Node root, String key)
{
if(root == null)
{
root = new Node(key);
return root;
}
if(key.compareTo(root.toString()) == -1)
{
root.setLeft(insertRec(root.getLeft(), key));
}
else if(key.compareTo(root.toString()) == 1)
{
root.setRight(insertRec(root.getRight(), key));
}
return root;
}
public Node search(String key)
{
return root == null ? null : root.getKey(key);
}
public void printPostOrder(Node node)
{
if(node == null)
return;
printPostOrder(root.getLeft());
printPostOrder(node.getRight());
System.out.print(node.getKey("") + ", ");
}
public void printInOrder(Node node)
{
if(node == null)
return;
printInOrder(node.getLeft());
System.out.print(node.getKey("") + ", ");
printInOrder(node.getRight());
}
public void printPreOrder(Node node)
{
if(node == null)
return;
System.out.print(node.getKey("") + ", ");
printPreOrder(node.getLeft());
printPreOrder(node.getRight());
}
public void printPostOrder()
{
printPostOrder(root);
}
public void printInOrder()
{
printInOrder(root);
}
public void printPreOrder()
{
printPreOrder(root);
}
public static void main (String args[]){
BinarySearchTree bs = new BinarySearchTree();
bs.insert("A");
bs.search("A");
}
}
and Node complete
public class Node
{
String key;
Node left, right;
public Node(String entry)
{
key = entry;
left = right = null;
}
public Node getLeft()
{
return left;
}
public Node getRight()
{
return right;
}
public Node getKey(String entry)
{
if(this.key.equals(key))
{
return this;
}
if(entry.compareTo(this.key) < 0)
{
return left == null ? null : left.getKey(entry);
}
else
{
return right == null ? null : right.getKey(entry);
}
}
public void setLeft(Node left)
{
this.left = left;
}
public void setRight(Node right)
{
this.right = right;
}
}
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
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.