Recursion while adding nodes in tree data structure - java

I'm new to understanding and learning data structures.I have tried to implement Tree data structure after searching some tutorials.It seems well but i don't understand the recursive behavior which was a bit strange here.Can someone help me in understanding the code.
I have included some print statements to understand the recursive flow but was not able to understand why the current refernce is not being returned?
public class TreeCheck {
Node root;
private Node addRecursive(Node current, int value) {
if (current == null) {
return new Node(value);
}
if (value < current.value) {
current.left = addRecursive(current.left, value);
} else if (value > current.value) {
current.right = addRecursive(current.right, value);
} else {
// value already exists
return current;
}
System.out.println("current is "+current.value); //Please compare in the
image why the
return current;
}
public void add(int value) {
root = addRecursive(root, value);
System.out.println("value is "+root.value);
}
public static void main(String h[]){
TreeCheck bt = new TreeCheck();
bt.add(6);
bt.add(4);
bt.add(8);
bt.add(3);
bt.add(5);
bt.add(7);
bt.add(9);
}
class Node {
int value;
Node left;
Node right;
Node(int value) {
this.value = value;
right = null;
left = null;
}
}
Why the current statement is being printed twice and always returns the root element only when the current is re-assigned sometimes?

It isn't printing it right for the following reasons:
First, your add method is always printing "value is " + root.value", which is confusing when trying to figure out how the program adds values.
Second, your add method prints after the value has been inserted, I would restructure it so that it prints the value to be inserted first, and then the path in which the nodes are being checked:
public void add(int value) {
// you always printed out the value of the root node with every call to this method
// I updated it to reflect the input argument
System.out.println("\nvalue is " + value);
root = addRecursive(root, value);
}
Now each block is its own insertion and the program flow is easier to trace.
Next: current is actually printing correctly, just in reverse order. Let us say you are inserting 5, the current nodes to be printed will be: the parent of 5, which is 4, then the parent of 4, which is 6.
This image might help to visualize the tree (sorry for my ugly hand writing)
If you want to change the order, do it like this (place the print of current before the if statement):
private Node addRecursive(Node current, int value) {
if (current == null) {
return new Node(value);
}
System.out.println("current is " + current.value);
if (value < current.value) {
current.left = addRecursive(current.left, value);
} else if (value > current.value) {
current.right = addRecursive(current.right, value);
} else {
// value already exists
return current;
}
return current;
}
Furthermore, if you would like to see if your insertion into a binary search tree works, you can use this method to print your tree in ascending order:
public void inOrderPrint(Node node){
if (node.left != null) {
inOrderPrint(node.left);
}
System.out.println(node.value);
if (node.right != null) {
inOrderPrint(node.right);
}
}
And call it like this in your main:
public static void main(String h[]) {
TreeCheck bt = new TreeCheck();
bt.add(6);
bt.add(4);
bt.add(8);
bt.add(3);
bt.add(5);
bt.add(7);
bt.add(9);
System.out.println("-------");
bt.inOrderPrint(bt.root);
}
I hope that was helpful and that I explained it clearly. Please comment if I made an incorrect statement and I will edit the post accordingly.

https://www.geeksforgeeks.org/binary-search-tree-set-1-search-and-insertion/
Go through the above article it should help.
Happy Learning !!

Related

JAVA: My Linkedlist is only printing my head element and nothing else

I have written my own linked list and am reading integers from a file into the list and printing them out. However, only the head of my list is printing and nothing else. I've been staring at this code for so long I feel insane, can anyone help?
Method in a separate 'files' class that reads in a file of integers separated by whitespace. This method will take the next integer and add it to my linked list.
public void readValues() {
LinkedList list = new LinkedList();
while(scan.hasNextInt()) {
Integer someData = scan.nextInt();
list.addNode(someData);
}
list.printList();
}
This method is in my LinkedList class which takes the data sent from my readValues method in my files class.
public void addNode(Integer someData) {
myNode = new LinkedNode(someData,null);
//initialize node if this is first element
if (head == null) {
head = myNode;
size++;
}
else if (myNode.getNext() == null) {
myNode.setNext(myNode);
size ++;
}
else if (myNode.getNext() != null) {
while(myNode.getNext() != null) {
myNode = myNode.getNext();
}
myNode.setNext(myNode);
size++;
}
}
This method is also in my LinkedList class and successfully prints the head of my list which with my data is the number 40 followed by ---> and then nothing else. It should print ever other integer read in from my file.
public void printList() {
LinkedNode current = head;
if (head == null) {
System.out.print("list is empty");
return;
}
while(current != null) {
System.out.print(current.getElement());
System.out.print(" --> ");
current = current.getNext();
}
}
LinkedNode class:
public class LinkedNode {
Integer data;
LinkedNode next;
public LinkedNode(Integer someData, LinkedNode next) {
this.data = someData;
this.next = null;
}
public int getElement() {
return data;
}
public void setElement(Integer data) {
this.data = data;
}
public LinkedNode getNext() {
return next;
}
public void setNext(LinkedNode next) {
this.next = next;
}
public String toString() {
return data + "";
}
}
Your code has a small bug in the if else conditions in your addNode() method due to which your data is not getting added in the list.
Root Cause
When you add a new node to your list,
In the first iteration
The head is currently null and hence the first if conditions becomes true and your first node gets added (That's why you got the data 40).
In the Subsequent iteration(s)
your else if condition checks the myNode's next pointer which will always be null (as per the constructor) and thus it's next pointer points towards itself. The nodes created from here do not become the part of the list as the next pointer of head was never assigned to any of these and these nodes also point to themselves only.
Solution
I made a little modification in the if else conditions:
public void addNode(Integer someData) {
LinkedNode myNode = new LinkedNode(someData,null);
//initialize node if this is first element
if (head == null) {
head = myNode;
size++;
}
else if (head.getNext() == null) {
head.setNext(myNode);
size ++;
}
else if (head.getNext() != null) {
System.out.println("in second else if");
LinkedNode n = head;
while(n.getNext() != null) {
n = n.getNext();
}
n.setNext(myNode);
size++;
}
}
PS: Try debugging your code with dry run, it's a great mental exercise and helps in boosting the learning curve significantly too. All the best! :)
The problem is with your addNode() method. Inside the addNode() method you are first creating a new node named mynode. Now when the head is null it sets head to mynode, thats ok. But when the head is not null the mynode is not being added to the list. Thats why only the first element exist and other's are getting lost.
Hope this helps. Let me know if I can help with anything else. Happy coding!

Adding Several Items To A Linked-List

I am creating an implementation of a linked list and am having trouble with the add method. After testing it with several entries, my size() method always returns 1. what am i doing wrong.
public class Node {
public int data;
public Node next;
public Node(int data){
this.data = data;
}
}
public class LinkedList {
public Node first;
public Node last;
public LinkedList(){
first = null;
last = null;
}
public void add(int data){
Node newNode = new Node(data);
if(first == null){
first = newNode;
} else {
add(first, newNode);
}
}
public void add(Node currentNode, Node newNode){
if(currentNode.next != null){
add(currentNode.next, newNode);
}
currentNode.next = newNode;
}
public int size(){
if(first == null){
return 0;
}
else{
return size(first);
}
}
public int size(Node currentNode){
//Count Starts At One Because First = 1.
int count = 1;
if(currentNode == null){
return count;
}
else {
count++;
return size(currentNode.next);
}
}
}
You forgot the else in the 2-arg form of add. As it stands,
if(currentNode.next != null){
add(currentNode.next, newNode);
}
currentNode.next = newNode;
will always add the new node to first and to all the other nodes in the list. If currentNode.next = newNode appears in an else clause, it will be added correctly only to the end.
Additionally, your size method always returns 1 because the final branch always returns 1. To fix this, change
count++;
return size(currentNode.next);
to
return 1 + size(currentNode.next);
Also, replace return count; with return 1;.
Basically, your implementation is almost correct. size(Node) should return the size of the list starting with that node. If the node does not have a next, the size is 1. Otherwise, its the current node (1) + the size of the remaining tail.
You should make the 2-arg versions of add and the 1-arg version of size private since you don't want to expose the internals of your list to the public (in fact, the Node class should be a private class as well).
Additionally, you never use the last field of your class. You can either remove it, or use it to avoid the need for recursion completely in add. In the latter case, you will have to update it correctly with every new addition.
In place of return size(currentNode.next); try this return count + size(currentNode.next);
It will fix the count problem given that, the list is fine. But checking your code at a glance looks like the list addition code is also buggy.

Recursively count the number of leaves in a binary tree without given parameters

I am struggling to figure out how to code a recursive algorithm to count the number of leaves in a Binary Tree (not a complete tree). I get as far as traversing to the far most left leaf and don't know what to return from there. I am trying to get the count by loading the leaves into a list and getting the size of that list. This is probably a bad way to go about the count.
public int countLeaves ( ) {
List< Node<E> > leafList = new ArrayList< Node<E> >();
//BinaryTree<Node<E>> treeList = new BinaryTree(root);
if(root.left != null)
{
root = root.left;
countLeaves();
}
if(root.right != null)
{
root = root.right;
countLeaves();
}
if(root.left == null && root.right == null)
{
leafList.add(root);
}
return();
}
Elaborating on #dasblinkenlight idea. You want to recursively call a countleaves on root node & pass back the # to caller. Something on the following lines.
public int countLeaves() {
return countLeaves(root);
}
/**
* Recursively count all nodes
*/
private static int countLeaves (Node<E> node) {
if(node==null)
return 0;
if(node.left ==null && node.right == null)
return 1;
else {
return countLeaves(node.left) + countLeaves(node.right);
}
}
Edit: It appears, a similar problem was previously asked counting number of leaf nodes in binary tree
The problem with your implementation is that it does not restore the value of member variable root back to the state that it had prior to entering the method. You could do it by storing the value in a local variable, i.e.
Node<E> oldRoot = root;
... // your method goes here
root = oldRoot;
However, a better approach is to take Node<E> as an argument, rather than relying on a shared variable:
public int countLeaves() {
return countLeaves(root);
}
private static int countLeaves (Node<E> node) {
... // Do counting here
}

BST Only Keeps Last Inserted Value and Makes it Root

I'm trying to populate a binary search tree using an insert(), however when every I 'print' the contents of my BST, I only get the last item that was inserted into the BST. What do I need to fix to make sure all of my value are retaining in the BST?
From debuggin, I think that my problem is that my public void insert() is setting the new value to root evertime it is called. I don't know how to fix it?
Here is my BST CLass:
public class BinarySearchTree<T extends Comparable<T>> {
private class BinarySearchTreeNode<E>{
public BinarySearchTreeNode<E> left, right;
private E data;
private BinarySearchTreeNode (E data) {
this.data = data;
}
}
private BinarySearchTreeNode<T> root;
public boolean isEmpty() {
return root == null;
}
private BinarySearchTreeNode<T> insert(T value, BinarySearchTreeNode<T> ptr) {
if (ptr == null){
ptr = new BinarySearchTreeNode<>(value);
return ptr;
}
int compare = value.compareTo(ptr.data); //when ptr != null, this line and below should execute for each bstStrings.inster(x)
/* pass the value (s1...sN) when compared to (ptr.data) to compare
* when value and ptr.data == 0 re
*/
if (compare == 0) {
return ptr;
}
if (compare < 0) {
while (ptr.left != null){
ptr = ptr.left;
if (ptr.left == null) {//found insertion point
BinarySearchTreeNode<T> node = new BinarySearchTreeNode<>(value);
ptr = ptr.left;
ptr = node;
return ptr;
}
}
}
else {
return insert(value, ptr.left);
}
if (compare > 0) {
if (ptr.right == null) {
BinarySearchTreeNode<T> node = new BinarySearchTreeNode<>(value);
ptr = ptr.right;
ptr = node;
return ptr;
}
}
else {
return insert(value, ptr.right);
}
return ptr;
}
public void insert(T value) {
root = insert(value, root); //****Where I believe the problem is******
}
private void printTree(BinarySearchTreeNode<T>node){
if(node != null){
printTree(node.left);
System.out.println(" " + node.data);
printTree(node.right);
}
}
public void printTree(){
printTree(root);
System.out.println();
}
}
For added context here is my Main() where I am calling the insert() and trying to insert strings into the BST:
public class Main {
public static void main(String[] args) {
BinarySearchTree<String> bstStrings = new BinarySearchTree<String>();
String s = "Hello";
String s1 = "World";
String s2 = "This Morning";
String s3 = "It's";
bstStrings.insert(s);
bstStrings.insert(s1);
bstStrings.insert(s2);
bstStrings.insert(s3); //the only inserted value that is printed below
bstStrings.printTree();
System.out.println();
System.out.println("You should have values above this line!");
}
}
Lastly my console output:
It's
You should have values above this line!
Some hints:
I don't see any recursive calls inside insert. How would you traverse the BST without appropriate recursive calls (into the left or right subtree of the current node based on the value)? I do see some commented out code that looks like it would perform those calls. Why are they commented out?
You're returning the newly inserted node, which you're then setting as root. This will set the root to point to the new node every time. I don't think that's what you want.
If you're trying to handle the special case where the tree is empty, all you need to do is check to see if root is null, then set the new node to that.
There really is no need to return ptr. Since your BST maintains a reference to root, you always have a reference to the root of the tree. Every time you insert, you start with the root and then recursively traverse the tree until you find a suitable place to insert the new node. If you really must return the reference, then you most certainly should not be setting root to that new node!
Here is some pseudocode to help you out:
// Recursive function that inserts a value into a BST
function insert(node, value):
//Handles the case where you have no nodes in the tree, so root is null
if node is null:
node = new Node(value)
// If the value is lesser than the current node's value, we need to insert it
// somewhere in the right subtree
else if value < node.value:
if node.right is null:
// This node doesn't have a right child, so let's insert the new node here
node.right = new Node(value)
else:
// This node has a right child, so let's go further into this subtree to
// find the right place to insert the new node
insert(node.right, value)
// If the value is greater than the current node's value, we need to insert it
// somewhere in the left subtree
else if value > node.value:
if node.left is null:
// This node doesn't have a left child, so let's insert the new node here
node.left = new Node(value)
else:
// This node has a left child, so let's go further into this subtree to
// find the right place to insert the new node
insert(node.left, value)
else:
// A node with this value already exists so let's print out an erro
error("Node with that value already exists")
end function

Problem in binary tree; need help

can you help me please? I am making a binary tree with node insertion. How can I insert the new node to the current node in respect of BST rule?
Example: first the root is empty.
Input number: 50
This will display "Success!"
Insert number: 40
Successfully inserted in the left subtree of 50
insert number: 20
successfully inserted in the left subtree of 40
insert number: 80
successfully inserted in the right subtree of 50
Can you help me please? Thank you in advance hoping for your positive response...
Here's my code:
class Node
{
public int num;
public Node llink;
public Node rlink;
}
public class BinaryTreeOperations
{
//public Node llink=null;
// public Node rlink=null;
private Node temp;
private Node current;
private Node root;
public boolean isEmpty()
{
return root==null;
}
public void insertNum(int n)
{
temp=null;
current=null;
Node newNode = new Node();
newNode.num=n;
newNode.llink=null;
newNode.rlink=null;
if(isEmpty())
{
root=newNode;
System.out.println("Successfully inserted!");
}
else
{
temp=root;
while(temp!=null)
{
current = temp;
root = current;
temp=null;
}
if(n<current.num)
{
current.llink=newNode;
//current.llink=temp;
System.out.println("inserted on the left subtree " +current.num);
}
else
{
newNode.rlink=newNode;
System.out.println("inserted on the right subtree "+current.num );
}
}
}
Your while loop seems wrong. What you really want to do is start at the root and traverse the tree until you reach the node which will serve as the parent of your new node. Below you are not doing any traversal or inspection to find where the new node should go. That is what you really need to be doing.
while(temp!=null) {
current = temp;
root = current;
temp=null;
}
Should be something like this:
while(parent not found) {
if (new node is smaller than current) {
if (current has left child) {
assign left child to current and loop
} else {
make current the parent of the new node
}
} else {
....
}
}
else
{
temp=root;
while(temp!=null)
{
current = temp;
root = current;
temp=null;
}
This loop will only ever run once. Probably not what you intended. :)
if(n<current.num)
{
current.llink=newNode;
//current.llink=temp;
System.out.println("inserted on the left subtree " +current.num);
}
else
{
newNode.rlink=newNode;
System.out.println("inserted on the right subtree "+current.num );
}
In one branch you are assigning to current.llink, in the other branch you are assigning to newNode.rlink. Oops. :)
Your methodology for adding to the binary search tree seems incorrect.
You need to read up on Binary Search Trees to figure out how you will maintain the structure of your tree.
Below is some code that shows how to add to a Binary Search Tree, but I define a tree as empty if it contains no data.
public boolean isEmpty() {
return data == null;
}
The rest of the code is pretty self explanatory and should help you figure out how to add to the tree to maintain order.
public boolean add(Comparable target) {
if(isEmpty()) {
setData(target);
this.setLeftTree(new BinarySearchTree());
this.setRightTree(new BinarySearchTree());
return true;
} else {
int comparison = getData().compareTo(target);
if(comparison == 0)
return false;
else {
if(comparison < 0) {
return getRightTree().add(target);
} else {
return getLeftTree().add(target);
}
}
}
}
Let me know if you have any other questions.

Categories