Binary search tree recursion does not work - java

I created this binary search tree. I wrote the insert method in 2 forms using loop and recursion. The recursion code although seems correct but does not work and I cannot figure out what the problem is. When I create the tree using insertRecursion method, the leftChild and rightChild always are null.
public class BinarySearchTree {
private class Node{
private int value;
private Node leftChild;
private Node rightChild;
public Node(int value){
this.value=value;
}
public String toString(){
return ""+this.value;
}
}
private Node root;
public BinarySearchTree(int value){
root=new Node(value);
}
public void insertRecursion(int value){
Node current=root;
insertRecursionForm(current,value);
}
private Node insertRecursionForm(Node root, int value){
if(root==null){
root=new Node(value);
return root;
}
if(value<root.value){
return insertRecursionForm(root.leftChild,value);
}else{
return insertRecursionForm(root.rightChild,value);
}
}
public void insert(int value){
Node current=root;
while(true) {
if (value < current.value) {
if (current.leftChild == null) {
current.leftChild= new Node(value);
break;
}else{
current=current.leftChild;
}
}else if(value>current.value) {
if (current.rightChild == null) {
current.rightChild= new Node(value);
break;
}else{
current=current.rightChild;
}
}
}
}
}

Try it like this:
private Node insertRecursionForm(Node root, int value){
if(root==null){
root=new Node(value);
return root;
}
if(value<root.value)
{
root.leftChild = insertRecursionForm(root.leftChild,value);
}else
{
root.rightChild = insertRecursionForm(root.rightChild,value);
}
return root;
}
The problem with your previous code was that you only returned the value of the last inserted node. This is why you always had the left and right node be null.

Related

How to populate the BST and also print it in Inorder way

I am trying this code to populate the BST and then print it in the InOrder traversal format. But the root node is not getting populated compiling wihtout any error and Output is : "root is empty", so how to correct this code so that my BST gets populated in the Node root.
I tried to make Node root as static I thought it might be the case that root node might not be accessible from each method but it is not working, tried to change the name of the Node but it is also not working.
import java.util.*;
import java.io.*;
import java.lang.*;
class Node{
int data; Node left; Node right;
public Node(int data) {
this.data = data;
left = null;
right = null;
}
}
public class insert_tree {
static Node root;
insert_tree() //constructor
{
root = null;
}
public void addNode(int value) { // public method is called by the object and this public method calls the private method in which the root is also passed.
root = add(root, value);
}
private Node add(Node node, int value) {
if(node == null) {
return node;
}
if(value < node.data) {
node.left = add(node.left, value);
}
else if(value > node.data) {
node.right = add(node.right, value);
}
else {
return node;
}
return node;
}
private void inOrder(Node node) {
// node = root;
if(node != null) {
inOrder(node.left);
System.out.print(node.data + " ");
inOrder(node.right);
}
else {
System.out.print("root is empty");
}
//return null;
}
public void inorder() {
inOrder(root);
}
private void printRoot(Node root) {
System.out.println(root.data);
}
public void print() {
printRoot(root);
}
public static void main(String args[]) {
insert_tree obj = new insert_tree();
obj.addNode(20);
obj.addNode(14);
obj.addNode(25);
obj.addNode(10);
obj.addNode(16);
obj.addNode(25);
obj.addNode(21);
obj.addNode(30);
//printing the tree
obj.inorder();
}
}
The output should be the inorder traversal of the tree.
public void addNode(int value) { // public method is called by the object and this public method calls the private method in which the root is also passed.
root = add(root, value);
}
private Node add(Node node, int value) {
if(node == null) {
node = new Node(value);
}
else if(value == node.data) {
node.data = value;
}
else if(value < node.data) {
node.left = add(node.left, value);
}
else {
node.right = add(node.right, value);
}
return node;
}

How to remove from a Linked list in Java?

So I wrote my own linked list (and list node) in Java as a part of a homework.
Now, I'm trying to erase entries, but the function is not working.
I know the concept:
Search for node keeping the previous;
Tell previous node to point to next node;
Return or stop using the node so GC erases it.
For some reason it is not working. I can delete the node with the same value over and over. I'm afraid it is something related to Java pointers.
The code:
Node:
public class SimpleNode<E> {
private E value;
private SimpleNode<E> next;
public SimpleNode() {
this.value = null;
this.next = null;
}
public NoSimples(E data, SimpleNode<E> ref) {
this.value = data;
this.next = ref;
}
// Getters and Setters
}
List:
public class LinkedList<E> implements Iterable<SimpleNode<E>> {
private SimpleNode<E> head;
private int size = 0;
public LinkedList() {
this.head = new SimpleNode<E>();
}
public void add(SimpleNode<E> node) {
this.addFirst(node.getValue());
}
public void addFirst(E item) {
SimpleNode<E> nonde = new SimpleNode<E>(item, this.head);
this.head = node;
size++;
}
public void add(E value) {
this.addFirst(value);
}
public SimpleNode<E> removeFirst() {
SimpleNode<E> node = this.head;
if (node == null) {
return null;
} else {
this.head = node.getNext();
node.setNext(null);
this.size--;
return node;
}
}
public SimpleNodes<E> remove(E value) {
SimpleNode<E> nodeAnt = this.head;
SimpleNode<E> node = this.head.getNext();
while (node != null) {
if (node.getValue()!= null && node.getValue().equals(value)) {
nodeAnt.setNext(node.getNext());
node.setNext(null);
return node;
}
nodeAnt = node;
node = node.getNext();
}
return null;
}
// Other irrelevant methods.
}
Multiple Problems :
Think if you have a list 1,2,3,4. Now, if you try to remove 1, your code fails.
nodeAnt = node should be nodeAnt = nodeAnt.getNext(). Remember, the're all references, not Objects
Also, a recursive way might be easier to understand. For example, Here is how I implemented it
public void remove(E e){
prev = head;
removeElement(e, head);
System.gc();
}
private void removeElement(E e, Node currentElement) {
if(currentElement==null){
return;
}
if(head.getData().equals(e)){
head = head.getNext();
size--;
}else if(currentElement.getData().equals(e)){
prev.setNext(currentElement.getNext());
size--;
}
prev = prev.getNext();
removeElement(e, currentElement.getNext());
}
Note: I delete all occurrences of the Element, as I needed it. You may need it to be different.

Delete Item - Doubly Linked list using Tail Recursion

I am currently learning Doubly Linked Lists.
I have managed to convert write a doubly linked list that was nearly 100% functional. However I need to learn how to write it with tail recursion.
Below is my DLLNode code:
public class DLLNode
{
private DLLNode previous;
public DLLNode next;
private String value;
public DLLNode(String value)
{
this.value = value;
this.previous = previous;
this.next = next;
}
public DLLNode(String value, DLLNode next, DLLNode previous)
{
this.value = value;
this.next = next;
this.previous = previous;
}
public String GetDataItem()
{
return value;
}
public void setDataItem()
{
this.value = value;
}
public DLLNode GetPreviousNode()
{
return previous;
}
public void setPrevious(DLLNode previous)
{
this.previous = previous;
}
public DLLNode GetNextNode()
{
return next;
}
public void setNextNode(DLLNode next)
{
this.next = next;
}
public void addItem(String value) {
if(this.next == null) {
// Stopping condition
DLLNode newNode = new DLLNode(value);
this.next = newNode;
} else {
// Recurse
this.next.addItem(value);
}
}
}
I have managed to get my AddItem working using tail recursion and I'm now looking into getting delete Item working. I'm guessing that like addItem I need deleteItem adding to my DLLNode.
Below is my DoublyLinkedList class:
public class DoublyLinkedList
{
private int noOfItems;
private DLLNode head;
private DLLNode tail;
// Default constructor
public DoublyLinkedList()
{
head = null;
tail = null;
this.noOfItems = 0;
}
public void DeleteItem(int index)
{
if (index ==0)
{
System.out.println("Out of Bounds");
}
if (index > noOfItems)
{
System.out.println("Out of Bounds");
}
if (head == null)
{
System.out.println("No Item to remove");
}
else if (index == 1)
{
head = head.GetNextNode();
noOfItems--;
}
else
{
int position = 0;
DLLNode currentNode = head;
while (currentNode != null) {
if (position == index-1) {
currentNode.setNextNode(
currentNode.GetNextNode().GetNextNode());
noOfItems--;
break;
}
currentNode = currentNode.GetNextNode();
position++;
}
}
}
}
Any tips on where I can get started with converting this code would be greatly appreciated.
Kind Regards,
Ben.
P.S. Apologies for the way the code has formatted - I've tried to fix it but it won't seem to sort. Can anyone good at formatting code on her please try and sort it out?
private void DeleteItemHelper(final int indexToDelete, int curIndex, DLLNode curNode) {
if (curIndex == indexToDelete) {
// Handle removing a node with both a previous and next nodes.
}
else {
DeleteItemHelper(indexToDelete, curIndex + 1, curNode.getNextNode());
}
}
public void DeleteItem(int index) {
DeleteItemHelper(index, 0, head);
}
Without further testing I think that you are forgetting to re-set the head reference of the node following the removed node:
if (position == index-1) {
// Tail of currentNode is set to the node following
// next node, but head of that node still points to the
// node which should be removed from list
currentNode.setNextNode(
currentNode.GetNextNode().GetNextNode());
noOfItems--;
break;
}

Why is the recursive insertion method of the BST not working

I wrote the following code to implement the recursive insert method for the BST. But when I print the tree in walk over order it prints the original tree before insertion. It seems as if the element was not inserted. Please help me out. Thanks in advance. Also please suggest the change in code. By the way, the intial tree in walk over order is 2 5 5 6 7 8.
package DataStructures;
class TreeNode {
private TreeNode parent;
private TreeNode childLeft;
private TreeNode childRight;
private int key;
public TreeNode(){
}
public TreeNode(int key) {
this(key, null);
}
public TreeNode(int key, TreeNode parent) {
this(key, parent, null, null);
}
public TreeNode(int key, TreeNode parent, TreeNode childLeft, TreeNode childRight) {
this.key = key;
this.parent = parent;
this.childLeft = childLeft;
this.childRight = childRight;
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public TreeNode getParent() {
return parent;
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
public TreeNode getChildLeft() {
return childLeft;
}
public void setChildLeft(TreeNode childLeft) {
this.childLeft = childLeft;
}
public TreeNode getChildRight() {
return childRight;
}
public void setChildRight(TreeNode childRight) {
this.childRight = childRight;
}
}
public class BinarySearchTreeBasicTest {
private static class BinarySearchTree {
private TreeNode root;
private TreeNode maxNode = new TreeNode(0);
public BinarySearchTree(TreeNode root) {
this.root = root;
}
public void printTheTreeInOrderWalk(TreeNode x) {
if (x != null) {
printTheTreeInOrderWalk(x.getChildLeft());
System.out.print(x.getKey() + " ");
printTheTreeInOrderWalk(x.getChildRight());
}
}
public void insertNode(TreeNode node, int key){
if (node == null){
node = new TreeNode(key);
}
else{
if (node.getKey() > key){
insertNode(node.getChildLeft(), key);
} else if (node.getKey() < key){
System.out.println("k");
insertNode(node.getChildRight(), key);
} else{
// dont do anything
}
}
}
}
public static void main(String[] args) {
TreeNode rootNode = new TreeNode(6);
BinarySearchTree tree = new BinarySearchTree(rootNode);
TreeNode node1 = new TreeNode(5);
TreeNode node2 = new TreeNode(7);
rootNode.setChildLeft(node1);
rootNode.setChildRight(node2);
node1.setParent(rootNode);
node2.setParent(rootNode);
TreeNode node3 = new TreeNode(2);
TreeNode node4 = new TreeNode(5);
node1.setChildLeft(node3);
node1.setChildRight(node4);
node3.setParent(node1);
node4.setParent(node1);
TreeNode node5 = new TreeNode(8);
node5.setParent(node2);
node2.setChildRight(node5);
tree.insertNode(rootNode, 3);
tree.printTheTreeInOrderWalk(rootNode);
}
}
In your insertNode() method, you are just creating a new node; you are never adding the newly created node to its parent. You should check whether you are going to insert here or not or you should return the newly returned node and set it accordingly.
If you don't want too much deviation from your current program, you can make the following changes.
public void insertNode(TreeNode node, int key) {
if (node.getKey() > key) {
if (node.left == null) { //check if you want to insert the node here
TreeNode newNode = new TreeNode(key);
node.left = newNode;
} else {
insertNode(node.getChildLeft(), key);
}
} else if (node.getKey() < key) {
if(node.right == null){ //check if you want to insert the node here
TreeNode newNode = new TreeNode(key);
node.right = newNode;
} else {
insertNode(node.getChildRight(), key);
}
} else {
// don't do anything
}
}
In Java, parameters are passed by value. In insertNode, if you don't do anything else with the node, the line node = new TreeNode(key); will not do anything useful.
The typical implementation of an insertion in a tree works by returning the TreeNode that will replace the previous one:
private TreeNode insertNode(TreeNode node, int key){
if (node == null){
node = new TreeNode(key);
}
else{
if (node.getKey() > key){
node.setChildLeft(insertNode(node.getChildLeft(), key));
} else if (node.getKey() < key){
node.setChildRight(insertNode(node.getChildRight(), key));
} else{
// dont do anything
}
}
return node;
}
Going a bit further, the previous method should actually be private. The public method should look like this:
public void insertNode(int key){
root = insertNode(root, key);
}

Bst tree delete() method doesnt work

I am currently implementing a Binary Search Tree and I am wondering, why my delete() method doesn't work...
My findMin() method does work, I have tested it out so far.
I type in a key, which doesn't exist in the three and I get the right exception, but whenever I type in a key, which is existing, it just doesn't remove the node from the three...
So here is my code so far:
import java.util.NoSuchElementException;
public class Bst {
Node root;
Node head;
Node tail;
public Bst(){
root = null;
}
public void insert (Node root, int key){
Node newNode=new Node(key);
if(root==null){
root=newNode;
}
if(key<=root.getKey()){
if (root.getLeft()!=null){
insert(root.getLeft(), key);
}
else{
root.setLeft(newNode);
}
}
if (key>=root.getKey()){
if (root.getRight()!=null){
insert(root.getRight(),key);
}
else{
root.setRight(newNode);
}
}
}
public void printTree(Node root){
if (root==null) return;
printTree(root.getLeft());
System.out.print(root.getKey() + " ");
printTree(root.getRight());
}
public Node treeToCDLL(Node root){
if (root == null){
return null;
}
Node leftTree=treeToCDLL(root.getLeft());
Node rightTree=treeToCDLL(root.getRight());
if (leftTree == null){
head=root;
}
else {
head=leftTree;
leftTree.getLeft().setRight(root);
root.setLeft(leftTree.getLeft());
}
if (rightTree==null){
head.setLeft(root);
root.setRight(head);
tail=root;
}
else{
tail=rightTree.getLeft();
head.setLeft(tail);
tail.setRight(head);
root.setRight(rightTree);
rightTree.setLeft(root);
}
return head;
}
public boolean find(Node root, int key){
Node current=root;
while(current!=null){
if(current.getKey()==key){
return true;
}
else if(current.getKey()>key){
current=current.getLeft();
}
else
current=current.getRight();
}
return false;
}
public void printList(Node head){
Node current = head;
while(current!=null){
System.out.print(current.getKey() + " ");
current=current.getRight();
if(current==head) break;
}
}
public Node findMin(Node root){
Node current=root;
if(root==null) return null;
else{
if(current.getLeft()!=null){
return findMin(current.getLeft());
}
}
return current;
}
public void delete(Node root, int key){
Node current=root;
if(root==null){
throw new NoSuchElementException("baum ist leer");
}
else{
if(current.getKey()>key){
delete(current.getLeft(), key);
}
else if(current.getKey()<key){
delete(current.getRight(),key);
}
else{
if(current.getLeft()==null && root.getRight()==null){
current=null;
}
else if(current.getLeft()==null){
Node tmp=current;
current=current.getRight();
tmp=null;
}
else if(current.getRight()==null){
Node tmp=current;
current=current.getLeft();
tmp=null;
}
else {
Node min=findMin(current.getRight());
Node tmp=current;
current=min;
tmp=null;
}
}
}
}
public static void main (String[]args){
Bst bst=new Bst();
Node root=new Node(4);
bst.insert(root, 2);
bst.insert(root, 10);
bst.insert(root, 3);
bst.insert(root, 5);
bst.insert(root, 6);
bst.insert(root, 0);
bst.delete(root, 2);
System.out.print("in-order traversal: ");
bst.printTree(root);
System.out.println();
System.out.print("Der gesuchte Knoten : " + bst.find(root,7));
System.out.println();
System.out.print("der kleinste Knoten : " + bst.findMin(root));
System.out.println();
System.out.print("circular doubly linked list: ");
Node head= bst.treeToCDLL(root);
bst.printList(head);
}
}
Node class:
public class Node {
private Node left;
private Node right;
private int key;
public Node(int key){
this.key=key;
left = null;
right = null;
}
public void setLeft(Node left){
this.left=left;
}
public Node getLeft(){
return left;
}
public void setRight(Node right){
this.right=right;
}
public Node getRight(){
return right;
}
public int getKey(){
return key;
}
}
I would be glad if someone could help me...
I tried out to find a solution the whole day, but it seems like I won't find it on my own
Here, by doing this current=min you are not changing node in tree, but simply replacing a local pointer (current).
Either rewrite values of this node by setters, of get update getLeft on parent of the node.
else {
Node min=findMin(current.getRight());
Node tmp=current;
current=min;
tmp=null;
}
In the last else part of the delete() method, you are just simply assigning null values that doesn't mean the references would point to the null value.
e.g When the matched node is a leaf node, you are simply assigning null value to the current variable. You should assign nullvalue to the left/right of current's parent. Assuming parent is the parent node of current node.
if(current.getLeft()==null && root.getRight()==null){
if(current == parent.getLeft()) {
parent.left=null;
} else {
parent.right == null;
}
}
These is same problem with other subsequent else blocks.
else if(current.getLeft()==null){
if(current == parent.left) {
parent.left= current.getRight();
} else {
parent.right = current.getRight();
}
}
else if(current.getRight()==null){
if(current == parent.left) {
parent.left= current.getLeft();
} else {
parent.right = current.getLeft();
}
}
You need to keep track of the parent node while traversing the tree.

Categories

Resources