NullPointerException adding data to BST - java

I am implementing a BST which has 3 classes:
BST, BSTNode and Profile.
BST class
public class BST {
private static BSTNode root;
private BSTNode parent;
BST() {
root = null;
}
public void insertProfile(Profile p) {
BSTNode newNode = new BSTNode(p);
if (root == null) {
root = newNode;
} else {
BSTNode focusNode = root;
BSTNode parent = null;
int compare = focusNode.getProfile().getName().compareTo(parent.getProfile().getName());
while (true) {
parent = focusNode;
if (compare < 0) {
focusNode = focusNode.left;
if (focusNode == null) {
parent.left = newNode;
return;
} else {
focusNode = focusNode.right;
if (focusNode == null) {
parent.right = newNode;
return;
}
}
}
}
}
}
}
When I add a single entry to the BST, it seems to work fine, but then when I add two or more entries to the BST, it gives me this error:
Exception in thread "main" java.lang.NullPointerException
at BST.insertProfile(BST.java:21)
at BSTMain.main(BSTMain.java:19)
I have been trying to resolve this for many hours, if anyone could hint where I am going wrong, would be very appreciative.

It's because of this code (in BST.java, right after the else statement in insertProfile:
BSTNode parent = null;
int compare = focusNode.getProfile().getName().compareTo(parent.getProfile().getName());
What you're doing is declaring that parent is null, but then calling a method (getProfile) on it, which is what is causing the NullPointerException. You have to instantiate parent first.

Correct insert BST to balance nodes and surround nullpointers.
public static Node insert(Node root,int data) {
if(root == null){
Node node = new Node(data);
root = node;
}else if (data > root.data) {
root.right = insert(root.right , data);
}else if (data < root.data){
root.left = insert(root.left , data);
}
return root;
}

Related

Insert Node at end of doubly linked list

I am trying to insert a node at the end of doubly linked list but when I run the add method, the code never finishes running. Here is the code below:
public class DoublyLinkedList<T> {
static class Node<T> {
T data;
Node<T> next;
Node<T> previous;
Node() {
data = null;
next = null;
previous = null;
}
Node(T value) {
data = value;
next = null;
previous = null;
}
}
private Node<T> head;
private int size;
public DoublyLinkedList() {
head = null;
}
public DoublyLinkedList(T value) {
head = new Node<T>(value);
size ++;
}
public void add(T value) {
Node<T> append = new Node<T>(value);
append.next = null;
if(head == null) {
append.previous = null;
head = append;
size ++;
return;
}
Node current = head;
while(current.next != null) {
current = current.next;
}
current.next = append;
append.previous = current;
size ++;
}
I pretty sure the line that says current.next = append is the problem, but I am not sure how to fix it. What am I doing wrong?

deleting a node from a binary search tree in java

I am making a boolean method that Deletes an element from the binary tree,
Returns true if the element is deleted successfully
, and Returns false if the element is not in the tree. The issue that I am having is that for some reason it is not deleting the node sometimes. I just want to know if I am doing anything wrong, thanks in advance.
here is my code:
public boolean delete(E e) {
BSTDelete<E> d = new BSTDelete<E>();
boolean deleted = d.delete(e, root);
if (deleted)
size -= 1;
return deleted;
}
public class BSTDelete<E extends Comparable<E>> {
public boolean delete(E e, TreeNode<E> root) {
if (root == null) {
return false;
}
if (e == root.element) {
if (root.right == null && root.left == null) {
root = null;
} else if (root.right == null) {
root = root.left;
} else if (root.left == null) {
root = root.right;
} else
root.element = minValue(root.left);
delete(root.element, root.left);
// Delete the inorder successor
} else if (e.compareTo(root.element) < 0) {
delete(e, root.left);
} else {
delete(e, root.right);
}
return true;
}
E minValue(TreeNode<E> root) {
E minv = root.element;
while (root.right != null) {
minv = root.right.element;
root = root.right;
}
return minv;
}
}
here is a test that keeps failing. The second assertEquals says that i.next() is "Beatrice" and not "Carl"
BST <String>b = new BST<String>();
b.insert("Arthur");
b.insert("Beatrice");
b.insert("Carl");
b.insert("Dagmar");
b.delete("Beatrice");
Iterator <String> i = b.iterator();
assertEquals(i.next(), "Arthur");
assertEquals(i.next(), "Carl");
assertEquals(i.next(), "Dagmar");
}
and here is my BSTInorderIterator class:
public class BSTInorderIterator<E extends Comparable<E>> implements
java.util.Iterator<E> {
int current = 0;
ArrayList<E> list = new ArrayList<E>();
private TreeNode<E> root;
public BSTInorderIterator(TreeNode<E> root) {
list = new ArrayList<E>();
inorder(root);
}
/** Inorder traversal from the root */
public void inorder() {
inorder(root);
}
/** Inorder traversal from a subtree */
public void inorder(TreeNode<E> root) {
if (root.left != null)
inorder(root.left);
list.add(root.element);
if (root.right != null)
inorder(root.right);
}
#Override
/** More elements for traversing? */
public boolean hasNext() {
return current < list.size();
}
#Override
/** Get the current element and move to the next */
public E next() {
return list.get(current++);
}
#Override
/** Remove the current element */
public void remove() {
// to do: make this work correctly
}
The delete method inside the class BSTDelete is a recursive method, however you're never returning the recursive method calls. Therefore your delete method will only ever return false when you call it with a like d.delete(e, root) where root is null.
For example even though delete(e, root.left) might return false because root.left is null your original method call will return true since you don't return the result of delete(e, root.left).
To fix this add return when you're calling the method recursively, this might only be a partial fix to your issue:
public boolean delete(E e, TreeNode<E> root) {
if (root == null) {
return false;
}
if (e == root.element) {
if (root.right == null && root.left == null) {
root = null;
} else if (root.right == null) {
root = root.left;
} else if (root.left == null) {
root = root.right;
} else
root.element = minValue(root.left);
return delete(root.element, root.left);
// Delete the inorder successor
} else if (e.compareTo(root.element) < 0) {
return delete(e, root.left);
} else {
return delete(e, root.right);
}
return true;
}

Rotating a Linked List Clockwise

I want to rotate my linked list clockwise by a certain amount.
private class Node {
private T data; // Entry in bag
private Node next; // link to next node
private Node(T dataPortion) {
this(dataPortion, null);
} // end constructor
private Node(T dataPortion, Node nextNode) {
data = dataPortion;
next = nextNode;
} // end constructor
} // end Node
public void leftShift(int num){
if (num == 0) return;
Node current = firstNode;
int count = 1;
while (count < num && current != null)
{
current = current.next;
count++;
}
if (current == null)
return;
Node kthNode = current;
while (current.next != null)
current = current.next;
current.next = firstNode;
firstNode = kthNode.next;
kthNode.next = null;
}
I managed to get my counter clockwise rotation to work but I'm kinda confused about how to get the clockwise rotation since I can't find previous nodes.
The example you asked:
private class Node {
private T data; // Entry in bag
private Node next; // link to next node
public Node(T dataPortion) {
this(dataPortion, null);
} // end constructor
public Node(T dataPortion, Node nextNode) {
data = dataPortion;
next = nextNode;
} // end constructor
T getObject() {
return data;
}
Node<T> getNext() {
return next;
}
} // end Node
public class Queue<T>{
 
private Node head;
private Node tail;
private String name;
public Queue(){
this("queue");
}
 
public Queue(String listName) {
name = listName;
head = tail = null;
}
public boolean isEmpty() {
return tail == null;
}
public void put(T item) {
Node node = new Node(item);
if (isEmpty()) // head and tail refer to same object
head = tail = node;
else { // head refers to new node
Node oldtail= tail;
tail=node;
oldtail.nextNode=tail;
}
}
public Object get() throws NoSuchElementException {
if (isEmpty()) // throw exception if List is empty
throw new NoSuchElementException();
 
T removedItem = head.data; // retrieve data being removed
 
// update references head and tail
if (head == tail)
head = tail = null;
else // locate new last node
{
head=head.nextNode;
} // end else
 
return removedItem; // return removed node data
}
public int size() {
int count = 0;
if(isEmpty()) return count;
else{
Node<T> current = head;
// loop while current node does not refer to tail
while (current != null){
count++;
if(current.nextNode==null)break;
current=current.nextNode;
}
return count;
}
public void shift(){
if(size()<=1)return;
T removed = get();
put(removed);
}
}
ListNode* Solution::rotateRight(ListNode* A, int B) {
if(A==NULL) return NULL;
ListNode *cur=A;
int len=1;
while(cur->next!=NULL){
cur=cur->next;
len++;
}
cur->next=A;
int preLen=len-B%len-1;
ListNode *pre=A;
while(preLen--)
pre=pre->next;
A=pre->next;
pre->next=NULL;
return A;
}

Difficulties with Binary Search Tree with Generics Implementation

I'm having an issue with implementing this BinarySearchTree listed below. For some context, I'm creating a binary search tree based off of an interface that requires generics and a comparable key.I think that there is a logic error in the code that is stumping me and it's in the insert method in the BinarySearchTree, but I'm not 100% sure.
Below is the class for my Node, which is used in my BST.
public class MyNodeClass<Key extends Comparable<Key>, Value>{
private Key key;
private Value value;
private MyNodeClass<Key,Value> left = null;
private MyNodeClass<Key,Value> right = null;
public MyNodeClass(Key key, Value val)
{
this.key = key;
this.value = val;
}
public void setKey(Key key){
this.key = key;
}
public void setValue(Value value){
this.value = value;
}
public Key getKey(){
return this.key;
}
public Value getValue(){
return this.value;
}
public void setLeft(MyNodeClass<Key, Value> l){
this.left = l;
}
public void setRight(MyNodeClass<Key, Value> r){
this.right = r;
}
public MyNodeClass<Key,Value> getLeft(){return this.left;}
public MyNodeClass<Key,Value> getRight(){return this.right;}
public int compareTo(Key that){
return(this.getKey().compareTo(that));
}
}
public class MyBinarySearchTree<Key extends Comparable<Key>, Value> implements BinarySearchTree<Key,Value> {
private MyNodeClass<Key, Value> root;
public MyBinarySearchTree(){
root = null;
}
#Override
public boolean isEmpty() {
return root == null;
}
#Override
public Value insert(Key key, Value val) {
MyNodeClass<Key,Value> newNode = new MyNodeClass<Key,Value>(key,val);
newNode.setKey(key);
newNode.setValue(val);
if(root==null){
root = newNode;
return(newNode.getValue());
}
else{
MyNodeClass<Key,Value> current = newNode;
MyNodeClass<Key,Value> parent;
while(true){
{
parent = current;
if(current.compareTo(key) == 1)
{
current = current.getLeft();
if(current == null)
{
parent.setLeft(newNode);
return parent.getLeft().getValue();
}
}
else if(current.compareTo(key) == -1){
current = current.getRight();
if(current == null)
{
parent.setRight(newNode);
return parent.getRight().getValue();
}
}
else{
if(current.compareTo(key) == 0){
current.setKey(key);
current.setValue(val);
return current.getValue();
}
}
}
}
}
}
#Override
public Value find(Key key) {
MyNodeClass<Key, Value> current = root;
while (current.compareTo(key) != 0)
{
if (current.compareTo(key) == 1)
{
current = current.getLeft();
} else {
current = current.getRight();
}
if(current == null)
return null;
}
return current.getValue();
}
#Override
public Value delete(Key key) {
MyNodeClass<Key,Value> current = root;
MyNodeClass<Key,Value> parent = root;
boolean isLeftChild = true;
while(current.compareTo(key) != 0) {
parent = current;
if (current.compareTo(key) == 1) {
isLeftChild = true;
current = current.getLeft();
} else {
isLeftChild = false;
current = current.getRight();
}
if(current == null)
return null;
}
if(current.getLeft() == null && current.getRight() == null) {
if (current == root) {
root = null;
} else if (isLeftChild) {
parent.setLeft(null);
} else{
parent.setRight(null);
}
return current.getValue();
}
else if(current.getRight() == null)
{
if(current == root) {
root = current.getLeft();
}
else if(isLeftChild) {
parent.setLeft(current.getLeft());
}
else{
parent.setRight(current.getLeft());
}
return current.getValue();
}
else if(current.getLeft() == null)
{
if(current == root)
root = current.getRight();
else if(isLeftChild)
parent.setLeft(current.getRight());
else
parent.setRight(current.getRight());
return current.getValue();
}
else
{
MyNodeClass<Key,Value> successor = getSuccessor(current);
if(current == root)
root = successor;
else if(isLeftChild)
parent.setLeft(successor);
else
parent.setRight(successor);
successor.setLeft(current.getLeft());
return current.getValue();
}
}
#Override
public String stringLevelOrder() {
return(LevelOrder(root));
}
private MyNodeClass<Key,Value> getSuccessor(MyNodeClass<Key,Value> deleteNode)
{
MyNodeClass<Key,Value> successorParent = deleteNode;
MyNodeClass<Key,Value> successor = deleteNode;
MyNodeClass<Key,Value> current = deleteNode.getRight();
while(current != null)
{
successorParent = successor;
successor = current;
current = current.getLeft();
}
if(successor != deleteNode.getRight())
{
successorParent.setLeft(successor.getRight());
successor.setRight(deleteNode.getRight());
}
return successor;
}
public static void main(String[] args)
{
MyBinarySearchTree<Double, MyStudent> BST = new MyBinarySearchTree<Double, MyStudent>();
MyStudent myStud1 = new MyStudent();
MyStudent myStud2 = new MyStudent();
MyStudent myStud3 = new MyStudent();
MyStudent myStud4 = new MyStudent();
MyStudent myStud5 = new MyStudent();
myStud1.init("Clarise", 1.1);
myStud2.init("Christopher", 1.2);
myStud3.init("John", 1.3);
myStud4.init("Chloe", 1.4);
myStud5.init("Goo", 1.5);
System.out.println(BST.insert(myStud1.getGPA(), myStud1));
System.out.println(BST.insert(myStud2.getGPA(), myStud2));
System.out.println(BST.insert(myStud3.getGPA(), myStud3));
System.out.println(BST.insert(myStud4.getGPA(), myStud4));
System.out.println(BST.insert(myStud5.getGPA(), myStud5));
System.out.println("Delete Key 1.0: " +BST.delete(1.3));
System.out.println("Delete Key 1.4: " +BST.delete(1.4));
System.out.println("Is Empty?: " +BST.isEmpty());
System.out.print("Find 3.9: "+ BST.find(3.9));
}
}
The result of the main is the following:
{Clarise:1.1}
{Christopher:1.2}
{John:1.3}
{Chloe:1.4}
{Goo:1.5}
Delete Key 1.0: null
Delete Key 1.4 null
Is Empty?: false
Find 3.9: null
I'm not entirely sure what the issue is and I've had some help from others, however they can't find the problem. Hoping that someone else can see something that we don't see.
In your insert method, after you've checked that root is not null, you are inserting newNode into the newNode instead of inserting it into the root.
This:
MyNodeClass<Key,Value> current = newNode;
MyNodeClass<Key,Value> parent;
Should be:
MyNodeClass<Key,Value> current = root;
MyNodeClass<Key,Value> parent;
P.S. any kind of testing would show you the problem with your insert within a minute. You could write a size() method and see that your inserts are not working, you could write a toString() method and see the state of the tree, finally you could debug.
MyNodeClass<Key,Value> current = newNode;
There is problem here.
If a tree is not empty, then your "current" should begin at root node. What you done is insert "newNode" to "newNode".
Change the code to be:
MyNodeClass<Key,Value> current = root;

Problems with Binary Tree node removal Java

I wanted to try and implement my own BST as an exercise, but I am stuck on the node removal. I cannot figure out why it doesn't work in some cases. I took the algorithm from a book, but when I test it with random elements, there are cases in which it does not remove the element, or even messes up their order so they are no longer sorted. What am I doing wrong and what would be a better way to accomplish this?
NOTE: All of the println() statements in the methods are there only for debugging purposes
class TreeNode<T extends Comparable<T>> {
T data;
TreeNode<T> left;
TreeNode<T> right;
TreeNode<T> parent;
TreeNode(T data) {
this.data = data;
}
boolean hasBothChildren() {
return hasLeftChild() && hasRightChild();
}
boolean hasChildren() {
return hasLeftChild() || hasRightChild();
}
boolean hasLeftChild() {
return left != null;
}
boolean hasRightChild() {
return right != null;
}
boolean isLeftChild() {
return this.parent.left == this;
}
boolean isRightChild() {
return this.parent.right == this;
}
}
public class BinaryTreeSet<T extends Comparable<T>> {
private TreeNode<T> root;
private void makeRoot(T element) {
TreeNode<T> node = new TreeNode<T>(element);
root = node;
}
private TreeNode<T> find(T element) {
TreeNode<T> marker = root;
TreeNode<T> found = null;
while (found == null && marker != null) {
int comparator = (marker.data.compareTo(element));
if (comparator > 0)
marker = marker.left;
else if (comparator < 0)
marker = marker.right;
else
found = marker;
}
return found;
}
private TreeNode<T> max(TreeNode<T> root) {
TreeNode<T> currentMax = root;
while (currentMax.hasRightChild()) {
currentMax = currentMax.right;
}
return currentMax;
}
// returns the inorder predecessor of node
private TreeNode<T> predecessor(TreeNode<T> node) {
return max(node.left);
}
// removes a given node with 0 or 1 children
private void removeNode(TreeNode<T> node) {
if (!node.hasChildren()) {
System.out.println("node with no children");
if (node.isLeftChild())
node.parent.left = null;
else
node.parent.right = null;
}
else {
System.out.println("node with 1 child");
if (node.isRightChild()) {
if (node.hasLeftChild())
node.parent.right = node.left;
else if (node.hasRightChild())
node.parent.right = node.right;
}
else if (node.isLeftChild()) {
if (node.hasLeftChild())
node.parent.left = node.left;
else if (node.hasRightChild())
node.parent.left = node.right;
}
}
node = null;
}
public BinaryTreeSet() {
root = null;
}
public void addElement(T element) {
if (root == null)
makeRoot(element);
else {
TreeNode<T> marker = root;
TreeNode<T> node = new TreeNode<T>(element);
boolean done = false;
while(!done) {
int comparator = marker.data.compareTo(element);
if (comparator > 0) {
if (marker.hasLeftChild())
marker = marker.left;
else {
marker.left = node;
done = true;
}
}
else if (comparator < 0) {
if (marker.hasRightChild())
marker = marker.right;
else {
marker.right = node;
done = true;
}
}
else
return;
node.parent = marker;
}
}
}
public boolean contains(T element) {
boolean found = (find(element) == null)? false : true;
return found;
}
public boolean removeElement(T element) {
TreeNode<T> node = find(element);
if (node == null)
return false;
// removal of a node with no children
if (!node.hasChildren()) {
if (node.isLeftChild()) {
node.parent.left = null;
}
else if (node.isRightChild()) {
node.parent.right = null;
}
}
// removal of a node with both children
else if (node.hasBothChildren()) {
TreeNode<T> pred = predecessor(node);
T temp = pred.data;
pred.data = node.data;
node.data = temp;
removeNode(pred);
}
// removal of a node with only 1 child
else {
if (node.isRightChild()) {
if (node.hasLeftChild())
node.parent.right = node.left;
else if (node.hasRightChild())
node.parent.right = node.right;
}
else if (node.isLeftChild()) {
if (node.hasLeftChild())
node.parent.left = node.left;
else if (node.hasRightChild())
node.parent.left = node.right;
}
}
node = null;
System.out.println("item removed: " + !contains(element));
return true;
}
}
please add following Method into BinaryTreeSet Class and call it,
which will show you current element list with Left/Right prefix.
boolean rootOncePrint = true;
public void printAllTree(TreeNode<T> startNode){
if(startNode == null) return;
//System.out.println(startNode.data);
if(rootOncePrint){
System.out.println("Root : " + startNode.data);
rootOncePrint = false;
}
if(startNode.hasChildren()){
if(startNode.hasLeftChild()){
printAllTree(startNode.left);
}
if(startNode.hasRightChild()){
printAllTree(startNode.right);
}
}
if(startNode != root){
T parentValue = startNode.parent.data;
T dataValue = startNode.data;
System.out.println(startNode.data + ((parentValue.compareTo(dataValue) > 0)?"L":"R"));
}
}
After Add this code, try to add/remove element into BinaryTreeSet so
you will get to know what's going on.
Found the bug that was causing me headaches. The problem was in the cases where I remove nodes with 0 or 1 child. I was not updating their parent nodes, so that messed up with the code. So, instead of, for example
if (node.hasLeftChild())
node.parent.right = node.left;
I should have written
if (node.hasLeftChild()) {
node.parent.left = node.left;
node.left.parent = node.parent;
}
in all cases where I deal with a single child. Also, I forgot to update the root, when the root is the target of the removeElement() function.
However, as it currently stands, I feel I have a lot of repetition in the code. I am yet to come up with a more elegant solution.
EDIT: There are other minor bugs as well, mainly in the isRightChild() and isLeftChild() functions, resulting in NullPointerException if the node in question does not have a parent.

Categories