Linked List, keep getting NullPointerException - java

I am trying to add Point into a linked list, in order to keep track of the frequency of each data entry. Everytime I run this code it gives me a NullPointerException. I don;t understand why, to me it seems as if after it adds the frequency it creates a gap but I cant seem to fix it.
if(firstNode == null)
{
addPair = new Pair(aData, 1);
firstNode = new Node(null, addPair, null);
lastNode = firstNode;
currentNode = firstNode;
numberOfNodes++;
}
else
{
currentNode=firstNode;
for(int count = 0; count<numberOfNodes; count++)
{
if(currentNode.data.fst().equals(aData))
{
addPair = new Pair(aData,currentNode.data.freq()+1);
if(count==0)
firstNode= new Node(currentNode,addPair,null);
currentNode = new Node(currentNode,addPair,null);
break;
}
if(count == (numberOfNodes-1) && currentNode.data.fst() !=(aData))
{
addPair = new Pair(aData,1);
Node newNode = new Node(currentNode, addPair, null);
currentNode.next = newNode;
lastNode = newNode;
numberOfNodes++;
break;
}
currentNode = currentNode.next;
}
}
numberOfEntries++;
private class Node
{
private Node previous;
private Pair data;
private Node next;
private Node(Node previousNode, Pair<T,Integer> addPair, Node nextNode)
{
previous = previousNode;
data = addPair;
next = nextNode;
}
}

If you are receiving a NPE at the line if(currentNode.data.fst().equals(aData)) then either currentNode == null or currentNode.data == null or currectNode.data.fst() == null. The first thing to do in diagnosing the problem is to find out which of these is the case. I suggest you put the following statements before this line and rerun your code:
assert currentNode != null;
assert currentNode.data != null;
assert currentNode.data.fst() != null;
Apart from that diagnosis there are a number of ways you could make your code safer. Firstly you really have no need to use a count to iterate through your linked list. Much safer would be to end when the next pointer is null:
for (Node current = firstNode; current != null; current = current.next) {
if (current.data.equals(aData)) {
// increment counter
return;
}
}

The main problem is in this line
firstNode= new Node(currentNode,addPair,null);
When you increase frequency of first node you are not setting the next Node, so you got list of only one node, but with size of many. Similar problem with line
currentNode = new Node(currentNode,addPair,null);
Also all first if statement is wrong. You are corrupting links in the list, it should be something like this
if (currentNode.data.fst().equals(aData)) {
addPair = new Pair(aData, currentNode.data.freq() + 1);
// create new node
Node c = new Node(currentNode.previous, addPair, currentNode.next);
// set links to new node
if (currentNode.previous != null) {
currentNode.previous.next = c;
}
if (currentNode.next != null) {
currentNode.next.previous = c;
}
if (count == 0) {
firstNode = c;
}
break;
}
To simplify your code and decrease possible errors I could recommend to write some function like incFrequency() in Pair class. Then in the loop do something like this
if (currentNode.data.fst().equals(aData)) {
currentNode.data.incFrequency();
break;
} else if(count == (numberOfNodes-1) && currentNode.data.fst() !=(aData)) {
// add new node to the end
}
Also you could rewrite you for loop
currentNode = firstNode;
// iterate through list
while (currentNode != null) {
// process currentNode
...
// move to the next node
currentNode = currentNode.next;
}

Related

Anomaly with linking objects in Java binary tree implementation

I have implemented a simple binary tree program, but there is a problem I encounter while traversing the tree, only root element is accessed. I suspect the nodes aren't linked. I tried my best to figure out the problem but didn't find anything wrong with my code.
I tried printing the data from the insertion function, right before exiting the function, which did print the data correctly.
public class BinaryTree {
Node root;
public void addNode(int data){
Node newNode = new Node(data);
if(root == null){
root = newNode;
}
else{
Node currentNode = root;
while(true){
if(data <= currentNode.data){
currentNode = currentNode.leftChild;
if(currentNode == null){
currentNode = newNode;
return;
}
}
else{
currentNode = currentNode.rightChild;
if(currentNode == null){
currentNode = newNode;
return;
}
}
}
}
}
public void inorderTraversal(Node currentNode){
if(currentNode != null){
inorderTraversal(currentNode.leftChild);
System.out.print(currentNode.data + " ");
inorderTraversal(currentNode.rightChild);
}
}
}
In fact you are not adding the new node correctly to the tree during the recursive step. The logic you should be using is when you a reach a node whose left or right pointer be null, and the new node belongs in that direction, you should add the new node either to the left or right. Otherwise, keep traversing until you reach such node.
while(true) {
if (data <= currentNode.data) {
if (currentNode.leftChild == null) {
currentNode.leftChild = newNode;
return;
}
else {
currentNode = currentNode.leftChild;
}
else {
if (currentNode.rightChild == null) {
currentNode.rightChild = newNode;
return;
}
else {
currentNode = currentNode.rightChild;
}
}
}
Keep in mind that the above simple algorithm for adding new nodes is not guaranteed to necessarily result in a balanced binary tree. To ensure that, you would have to add more logic which handle rebalancing.
You are not assigning the element to the left or right child. You are just assigning it to the local variable currentNode - which is not linked to the tree.
Follow the below code to put inside the while loop & it should work for you.
if(data <= currentNode.data){
if(currentNode.leftChild == null){
currentNode.leftChild = newNode;
return;
}
else {
currentNode = currentNode.leftChild;
}
}
else{
if(currentNode.rightChild == null){
currentNode.rightChild = newNode;
return;
}
else {
currentNode = currentNode.rightChild;
}
}

Java binary search tree loop returning null object reference?

I've written a remove function for a binary search tree that uses a while loop to navigate to the specific node to be removed. However, it's never getting there - it just iterates an unknown number of times and then gives me a NullPointerException.
I was wondering if it was an error in my traversal logic, but it's exactly the same as in my add function, which works perfectly.
void remove(Comparable newObject){
if (!isEmpty()){
Node curr = new Node();
curr = root;
boolean isFound = false;
while (!isFound){
if (curr.data.compareTo(newObject) == 0){
if (curr.hasChildren()){
Node replaceNode = new Node();
if (curr.leftChild == null){
replaceNode = curr.rightChild;
while (replaceNode.leftChild != null){
replaceNode = replaceNode.leftChild;
}
} else {
replaceNode = curr.leftChild;
while (replaceNode.rightChild != null) {
replaceNode = replaceNode.rightChild;
}
}
replaceNode.leftChild = curr.leftChild;
replaceNode.rightChild = curr.rightChild;
replaceNode.parent = curr.parent;
curr = replaceNode;
} else {
curr.data = null;
curr.parent = null;
}
listSize--;
isFound = true;
} else if (curr.data.compareTo(newObject) == 1) {
curr = curr.leftChild;
} else {
curr = curr.rightChild;
}
}
}
}
The data set I'm using yields a root with a left child, and then a right child off of that. The node to be removed is the first (left) child. However, the line that's giving the NullPointerException is
if (curr.data.compareTo(newObject) == 0){
and I'm really not sure at all what's causing this. Any and all help is appreciated greatly.
First of all don't initialize the variable as a new Node(), you're creating new Nodes you're not gonna use. Do it more like this:
void remove(Comparable newObject){
if (!isEmpty()){
Node curr = root;
and then again your replaceNode:
if (curr.hasChildren()){
Node replaceNode;
and I think it's not working, because in the end of the code, you rewrite curr to its children, but what if it doesn't have children? Then you try to compare null object with some object and that's why I think it throws NullPointerException.

Writing a method to sort a singly linkedlist in ascending order (java)

the method 'insertAscending' only gives me the first number even after i enter new ones. can anyone help with what i'm doing wrong? Thanks.
public class LinkedList13 {
// Private inner class Node
private class Node{
int data;
Node link;
public Node(){
data = Integer.MIN_VALUE;
link = null;
}
public Node(int x, Node p){
data = x;
link = p;
}
}
// End of Node class
public Node head;
public LinkedList13(){
head = null;
}
public void insertAscending(int data){
Node node = new Node();
node.data = data;
if (head == null)
head = node;
Node p = head;
while (p.link != null)
{
if (p.link.data > data)
{ node.link = p.link;
p.link = node;
break;
}
p= p.link;
}
}
}
Hint: is (p.link != null) ever true?
First of all, you should return after setting the head of the list (when the first element is added).
Second of all, you should handle the case where the newly inserted node is the smallest in the list (and therefore should come first). Your loop never compares the added node to the head of the list.
Finally, if the added element wasn't inserted in the while loop, it should be inserted after the while loop.
public void insertAscending(int data)
{
Node node = new Node();
node.data = data;
if (head == null) {
head = node;
return;
} else if (node.data < head.data) {
node.link = head;
head = node;
return;
}
Node p = head;
boolean added=false;
while (p.link != null)
{
if (p.link.data > data)
{
node.link = p.link;
p.link = node;
added = true;
break;
}
p = p.link;
}
if (!added)
p.link = node;
}
Check out your if condition if(p.link.data > data) the only way a node gets into the list is when that is true. This means, that, if the value of data being inserted it greater than (or equal to) everything that's been inserted so far, it will be discarded.
An easy way to fix this is change break to return and add p.link=node at the end (after the loop).

Single Linked List Insert at the tail

Every time I run this, it returns a bunch of: null, null, null for the items when I test the function out.
//enqueue()
//adds newItem to the back of this Queue
public void insertItemLast(Object newItem){//make sure that it is not empty so we can do the cool stuff in here
if(newItem == null)
return;//user inputs nothing
else {
Node P = new Node(newItem);
P.next = null;
if(head == null){
head = P;
tail = P;
//tail.next = null;
}else{
tail.next = new Node(newItem);
tail = new Node(newItem);
//tail.next = null;
}
}
numItems++;
}//end enqueque
You create two different links instead of just one.
Your else should be :
} else {
tail.next = new Node(newItem);
tail = tail.next;
}
Actually, you can make it even simpler. Just use P for the new link of the list in all cases :
public void insertItemLast(Object newItem){
if(newItem == null)
return;//user inputs nothing
else {
Node P = new Node(newItem);
P.next = null;
if(head == null) {
head = P;
tail = P;
} else {
tail.next = P;
tail = P;
}
}
numItems++;
}//end enqueque
You correctly assigned a new Node to tail.next, but you didn't update tail; you instead assigned another new Node to tail, effectively breaking the tail off of the list.
To advance the old tail to the new tail -- the newly inserted Node -- replace
tail = new Node(newItem);
with
tail = tail.next;

Deleting the second last node from a LinkedList in java

I'm working on a method that is supposed to delete the node prior to the last one,the logic seems quite fine with me, but when I tried to implement it in a project, it didn't work out. ( Oh and I'm using MyLinkedList)
here's the code:
public void deleteSec(){
Node current = head;
Node p = head.next;
Node q = null;
while(p.next!=null){
q = current;
current.next = p;
p = p.next;
}
q.next = p; // q.next = q.next.next;
}
What if your LL is empty? head will be null and this will cause an exception when you call head.next;
you have to take care of special cases like: empty LL, LL with one node, LL with two nodes.
Here is my code:
public void deleteSec() {
if (head == null) {
return;
}
if (head.next == null) {
return;
}
if (head.next.next == null) {
head = head.next;
return;
}
Node current = head;
Node p = current.next;
Node q = p.next;
while (q.next != null) {
current = current.next;
p = p.next;
q = q.next;
}
current.next = q;
}
if(myLinkedList.size() > 1) {
myLinkedList.remove(myLinkedList.size()-2);
}
well i personally compiled it,
Assuming the node class is named Node and you have a getNext() method that returns the next Node or null if this Node is the last node, you would do something like this.
if (head == null) // or if (first == null)
{
return; // There are no elements in the list.
}
Node currect = head; // This is the head, or Node current = first;
Node previous = null;
while (current.getNext() != null)
{
previous = current;
currrent = current.getNext();
}
Then do this to make the second to last pointer to next null.
if (previous != null)
{
previous.setNext( null );
}
else
{
// The list has 1 entry only.
head = null; // or first = null;
}
If deleting a second last node would be a common operation, as it is in my case, I would suggest an extra prev or previous node added to the Node construction.
Usually a linked list node would be
private static class Node<Item> {
private Item item;
private Node<Item> next;
}
But I modified it to be like
private static class Node<Item> {
private Item item;
private Node<Item> prev;
private Node<Item> next;
}
Thus, if you want to delete the second last, the implementation would be pretty straightforward:
oldSecondLast = last.prev; // Assumes last points to the last node
oldSecondLast.next = last;
last = oldSecondLast.prev;
oldSecondLast = null; // To avoid loitering

Categories

Resources