Inserting a node in BST - java

I am trying to insert nodes in my custom BST.The first time the insertData method is called , the new node is correctly inserted as the root.The problem is occuring in the second and subsequent calls.
Below is My code :
1.The Node Class =
package ishan.trees.tree;
class Node implements Comparable<Node> {
private int data;
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;
}
private Node leftChild;
private Node rightChild;
public Node(int data,Node leftChild,Node rightChild)
{
this.data=data;
this.leftChild=leftChild;
this.rightChild=rightChild;
}
#Override
public int compareTo(Node o) {
if(o.getData() > this.data)
return -1;
if(o.getData() < this.data)
return 1;
return 0;
}
}
The Tree Class =
package ishan.trees.tree;
public class Tree {
private Node root=null;
public Node getRoot() {
return root;
}
public void insertData(int data)
{
Node node=new Node(data,null,null);
insert(node,this.root);
}
private Node insert(Comparable<Node> node,Node root1)
{
if(root1==null)
{//insert as first element ie root
this.root=new Node(((Node)node).getData(),null,null);
}
else if(node.compareTo(root1) <0)
{
root1.setLeftChild(insert(node,root1.getLeftChild()));
}
else if(node.compareTo(root1) >0)
{
root1.setLeftChild(insert(node,root1.getRightChild()));
}
return root1;
}
}
3.Main Class =
package ishan.trees.usage;
import ishan.trees.tree.Tree;
public class Usuage {
public static void main(String a[])
{
Tree tree=new Tree();
tree.insertData(10); //---------1
tree.insertData(15); //---------2
tree.insertData(9); //---------3
tree.insertData(4); //---------4
}
}
when i debug the second call it is something like this:
insertData(15){
insert(15,10)
}
which makes a call to the insert method as ---->
insert(15,null)
I get this null every time and this results in the current node replacing the root node.
I cant figure out why during the call , the root1 reference is null and not pointing to my root?
More Info :
Its during the call from insertData() to insert() . say During my second call to insertData(15) , i make a call to insert(15,this.root) -->insert(node,root1) . but this root1 reference turns out to be null.but when i inspect this.root it is referring to the correct root node..
Thanks!

Alright here is dry run for your code,
Inserting 10.
When you insert first element, this API insert creates a new root for you as per your code and sets it value to 10,
now second insertion makes it interesting, watch what happenes
StackTrace
insertData(15);
insert(node,root) // here root is your actuall root, originally initialized when u inserted first
// it goes to last else if inside insert api
root1.setRightChild(insert(node,root1.getRightChild())); // see now, this apis actually calls insert again, coz new node value was greater then root value
// this is how next stack trace will look like, as root right child was null
insert(node,null); // observer second argument is null again
now as per your Insert code will end up creating root again(root1 argument is null, first condition is executed), discarding previously defined root. this is what is causing your issue you are overriding your root again and again.

After inserting first node i.e root, left and right node will be null. Next time while inserting left or right child node you are not checking that condition.
private Node insert(Comparable<Node> node,Node root1)
{
if(root1==null)
{//insert as first element ie root
this.root=new Node(((Node)node).getData(),null,null);
}
else if(node.compareTo(root1) <0)
{
if(root1.getLeftChild()==null)
root1.setLeftChild(node);
else
root1.setLeftChild(insert(node,root1.getLeftChild()));
}
else if(node.compareTo(root1) >0)
{
if(root1.getRightChild()==null)
root1.setRightChild(node);
else
root1.setRightChild(insert(node,root1.getRightChild()));
}
return root1;
}

Related

Best practice to build a BST from a Binary Tree

Im creating a Binary Search Tree in Java extending from a Binary Tree already implemented, but it does not work when I try to use some inherited methods. Let me explain:
Binary Tree:
public class BinaryTree<T>{
private Node<T> root;
public class Node<T>{
T value;
Node left;
Node right;
public Node(T value){
this.value = value;
this.left = null;
this.right = null;
}
}
public BinaryTree(){
...
}
public void printInOrder(){
...
}
}
BST:
public class BST extends BinaryTree<Integer>{
private Node<Integer> root;
public BST(Integer v){
super(v);
}
public void insert(Integer element){
insert(this.root, element);
}
private insert( Node node, Integer element){
if(node == null)
return;
if(node.value > value) {
if(node.left != null) {
insert(node.left, value);
}
else {
node.left = new NodeBST(value);
}
}else { // Node.value < element
if(node.right != null) {
insert(node.right, value);
}
else {
node.right = new NodeBST(value);
}
}
}
}
App:
public class App{
public static void main(String[] args){
BST bst = new BST(4);
bst.insert(2);
bst.insert(5);
bst.insert(3);
bst.insert(7);
bst.printInOrder(); //Here I got the problem
}
}
If I try to print it, it will just print the root (4) and will be null for the rest of the nodes. When I look what's going on inside, it turns out there is two roots:
BST.Node root, which contains all the nodes in the proper order
BinaryTree.Node root, which just contains the root and all the other nodes are null.
So I guess it creates the root correctly because I'm calling the super class in the BST' constructor, but when I creates a new Node in the insert method, it only appends it in BST.Node root (and not in the BinaryTree.Node root), therefore when I call print, which is implemented in BinaryTree, from BST in prints null :/
So my questios are:
How can I get to use the print method from BST in order to print all the values in BST.Node root?
What does prevent BinaryTree.Node root to be the same as BST.Node root?
What would be the best practice to do so?
Don't declare 'root' a second time in BST, it shadows the 'root' in the base class.
Either make 'root' in BinaryTree protected or provide the necessary accessors there, so subclasses can use it.

Cannot cast from inner class to class

I have a BinaryTree class which contains an inner class Node.
What I would like to do is to be able to insert some nodes in my BinaryTree tree by calling tree.insert(node). However, to keep it clean and consistent, I dont want to create an insert() method inside Node inner class. So I tried the code below, but I have an error: Cannot cast from BinaryTree.Node to BinaryTree.
What should I do?
BinaryTree class
public class BinaryTree {
Node root = null;
private class Node {
int value;
Node left;
Node right;
}
public BinaryTree(int v) {
root.value = v;
root.left = null;
root.right = null;
}
public void insert(Node n) {
/* Error */
if(n.value > root.value) ((BinaryTree) root.right).insert(n);
}
}
Main class
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
String[] str = sc.nextLine().split(" ");
BinaryTree tree;
for(int i = 0; i < str.length-1; i++) {
int val = Integer.parseInt(str[i]);
//tree.insert(node);
}
}
}
Thanks,
You don't need typecasting inside insert method. It should be like this:
public void insert(Node n) {
if(n.value > root.value)
insert(root.right);
}
To insert a node in a tree you need to define where to insert it, so your insert methods should be something like:
//insert a new node right to a node. not null safe
public void insert(Node newNode, Node rightTo) {
newNode.right = rightTo.right;
newNode.left = rightTo;
rightTo.right = newNode;
}
which does not require casting.
To find the rightTo node you could use:
//get the last node which has a value lower than `value`
//may return null
public Node getNodeWithValueLowerThan(int value) {
if(root == null) return null;
return getNodeWithValueLowerThan(root, value);
}
//recursive method. null safe
private Node getNodeWithValueLowerThan(Node node, int value) {
if(node == null) return null;
if(node.value > value) return node.left; //return previous node. may be null
return getNodeWithValueLowerThan(node.right, value);
}
To insert a node as a last node, you could use:
//insert a new node as last
public void insertLastNode(Node newNode) {
Node lastNode = getTail();
if(lastNode == null) {//empty tree
root = newNode;
return;
}
newNode.left = lastNode;
lastNode.right = newNode;
}
where getTail is something like:
//find last node
private Node getTail() {
if(root == null) return null;
return getTail(root);
}
//recursive method to find last node. not null safe
private Node getTail(Node node) {
if(node.right == null) return node;
return getTail(node.right);
}
Note: code was not tested so debug carefully.

Initiating a binary search tree using a rootNode that is null

I have this node class
public class Node {
Node right;
Node left;
int value;
Node(int value) {
this.value = value;
}
Node insertValue(int v){
if(this == null){
return new Node(v);
}
//Rest of the method
}
}
I want to make a rootNode that is the tree. If it is null, the tree is empty. Edit: The methods to populate the tree, find minimum, etc. must be recursive methods of class Node
class Main{
public static void main(String[] args) {
Node rootNode = null;
rootNode.insertValue(5);
}
}
Of course, since rootNode == null, I can't use it to call insertValue.
I am looking for a way to populate an empty tree(rootNode == null) with inner methods. Any tips on how I can do this?
You can create a new class Tree which contains (only) the root node and methods to work with like insertValue(). The Node class will become more or less a private helper class for the internals of the tree.
public class Tree {
private Node root;
public void insertValue(int v) {}
public int getSize() {}
public int getValue(int index) {}
}

Need guidance on creating Node class (java)?

I need to implement a Node class, where the basic methods are: getItem(), getNext(), setItem() and setNext(). I want the nodes to be able to store at least the default integer range in Java as the “item”; the “next” should be a reference or pointer to the next Node in a linked list, or the special Node NIL if this is the last node in the list.I also want to implement a two-argument constructor which initializes instances with the given item (first argument) and next node (second argument) , I've kind of hit a brick wall and need some guidance about implementing this , any ideas ?
I have this so far:
class Node {
public Node(Object o, Node n) {
}
public static final Node NIL = new Node(Node.NIL, Node.NIL);
public Object getItem() {
return null;
}
public Node getNext() {
return null;
}
public void setItem(Object o) {
}
public void setNext(Node n) {
}
}
While implementing the custom LinkedList/Tree, we need Node. Here is demo of creating Node and LinkedList. I have not put in all the logic. Just basic skeleton is here and you can then add more on yourself.
I can give you a quick hint on how to do that:
Class Node{
//these are private class attributes, you need getter and setter to alter them.
private int item;
private Node nextNode;
//this is a constructor with a parameter
public Node(int item)
{
this.item = item;
this.nextNode = null;
}
// a setter for your item
public void setItem(int newItem)
{
this.item = newItem;
}
// this is a getter for your item
public int getItem()
{
return this.item;
}
}
You can create a Node object by calling:
Node newNode = Node(2);
This is not a complete solution for your problem, the two parameter constructor and the last node link are missing, but this should lead you in the correct direction.
Below is a simple example of the Node implementation, (i renamed Item to Value for readability purpose). It has to be implemented somehow like this, because methods signatures seems to be imposed to you. But keep in mind that this is definely not the best way to implement a LinkedList.
public class Node {
public static final Node NIL = null;
private Integer value;
private Integer next;
public Node(Integer value, Node next) {
this.value = value;
this.next = next;
}
public Integer getValue() {
return this.value;
}
public Node getNext() {
return this.next;
}
public void setValue(Integer value) {
this.value = value;
}
public void setNext(Node next) {
this.next = next;
}
public boolean isLastNode() {
return this.next == Node.NIL || Node;
}
}
public class App {
public static void main(String[] args) {
Node lastNode = new Node(92, Node.NIL);
Node secondNode = new Node(64, lastNode);
Node firstNode = new Node(42, secondNode);
Node iterator = firstNode;
do () {
System.out.println("node value : " + iterator.getValue());
iterator = iterator.getNext();
} while (iterator == null || !iterator.isLastNode());
}
}
The node class that will be implemented changes according to the linked list you want to implement. If the linked list you are going to implement is circular, then you could just do the following:
public class Node {
int data;
Node next = null;
public Node(int data){
this.data = data;
}
}
Then how are you going to implement the next node?
You are going to do it in the add method of the circularLinkedList class. You can do it as follows:
import java.util.*;
public class CircularLinkedList {
public CircularLinkedList() {}
public Node head = null;
public Node tail = null;
public void add(int data) {
Node newNode = new Node(data);
if(head == null) {
head = newNode;
}
else {
tail.next = newNode;
}
tail = newNode;
tail.next = head;
}
public void displayList() {
System.out.println("Nodes of the circular linked list: ");
Node current = head;
if(head == null) {
System.out.println("Empty list...");
}
else {
do {
System.out.print(" " + current.data);
current = current.next;
}while(current != head);
System.out.println();
}
}
}

How to implement a sorted list

So i have a class called List and a class called SortedList which inherits the class List. Also there is a class called node. I have created another class which contains the printing method.
But, everytime i insert three names for example, and i call the printing method it only prints the last name i have inserted. So my question is: does this code makes a sorted list? And if so, why does it print only the last name?
List class:
public class List {
protected Node head;
protected int length;
public void list()
{
head=null;
length=0;
}
public boolean isEmpty()
{
return head==null;
}
public Node insert(Item a)
{
length++;
head=new Node(a, head);
return head;
}
SortList class:
public class SortList extends List {
private Node head;
public SortList()
{
this.head=null;
}
public Node getFirst()
{
return head;
}
public Node Insert(Item newitem)
{
Node node = new Node(newitem);
Node previous = null;
Node current = head;
while(current!=null && current.getValue().less(newitem))
{
previous=current;
current=current.getNext();
}
if(previous==null)
{
head=node;
}
else
{
previous.setNext(node);
node.setNext(current);
}
return head;
}
public void printlist()
{
Node current = head; //ΑΡΧΗ ΤΗΣ ΛΙΣΤΑΣ.
while(current!=null)
{
current.print();
current = current.getNext();
}
}
Node class:
public class Node {
private Item info;
private Node next;
public Node(Item dat)
{
info=dat;
}
public Node (Item dat, Node b)
{
info=dat;
next=b;
}
public Item getValue()
{
return info;
}
public void setNext(Node a)
{
next=a;
}
public Node getNext()
{
return next;
}
public void print()
{
info.print();
}
}
In your Implementation of List, you have a major bug in the insert() method:
public Node insert(Item a)
{
length++;
head=new Node(a, head);
return head;
}
You do not attach the new element to the end of the list, but rather replace the list's head each time, thus discarding the previous element.
This would explain why you always only see the last element you have inserted.
Edit: Turns out, the insert() method actually does work, since you set the reference to the next node in the node's constructor.
In your sorted list however, you have one insert case for which the next node is not set:
if(previous==null)
{
head=node;
}
I your sorted list, you don't set the next element in the constructor of the node. In all other cases, you set the next element in the insert() method, but not in this case. If the element you want to insert is the smallest in the list, previous is null, which is correct -- your new element is the new head of the list. Since you don't set the new element's successor, however, all elements that have been in the list are now gone.
If the last element you insert into the list is the smallest, the last element will also be the only one remaining and you print out only the last element.
Try setting the successor:
if(previous==null)
{
head=node;
head.setNext(current);
}

Categories