indexOf null exception - java

public int indexOf(X item)
{
Node <X> current = head;
int c = 0;
if (current.getValue().equals(item))
{
return c;
}
while (current != null)
{
current = current.getLink();
c++;
if (current.getValue().equals(item))
{
return c;
}
}
return -1;
}
.
#Test
public void testIndexOf()
{
LList<String> b = new LList<String>();
for (int i = 0; i < 20; i++)
b.add("str" + i);
assertEquals(19, b.indexOf("str0"));
assertEquals(0, b.indexOf("str19"));
assertEquals(-1, b.indexOf("not found"));
}
For some reason the last assertion is bringing up an error as Nullpointer exception. but i made it so when it does reach null to return -1, which is what i was trying to return in the third assertion in the test, what am i missing here?

The problem is this:
while (current != null)
{
current = current.getLink();
You ensure that current is not null . . . but then you immediately change current in a way that makes it possible for it to be null again. And you'll reach that case whenever item is not present in your linked-list.
You can fix this by rearranging the code a bit:
public int indexOf(X item)
{
Node <X> current = head;
int c = 0;
while (current != null)
{
if (current.getValue().equals(item))
{
return c;
}
current = current.getLink();
c++;
}
return -1;
}

while (current != null)
{
current = current.getLink();
c++;
if (current.getValue().equals(item))
{
return c;
}
}
return -1;
You are advancing to the next link after your null check. current.getLink is returning null.

Related

Why does the printing stop with no errors?

I try to print the result of boolean insert(K) in a for loop but after the first insertion the printing stops, that indicates the second insertion is not fully successful.
and inside method insert(K), the method "retrieves(K)" is called, to check if K has been already inserted.
for (int i = 100; i > 0; i--) {
System.out.println(m.insert(i +1, 22));
System.out.println("dd");
System.out.println(m.retrieve(i+1).first + ",,,"+m.retrieve(i+1).second);
System.out.println(i + " insertion done");
System.out.println("---------");
}
and the result is
-------------------
true
dd
true,,,22
100 insertion done
---------
true
dd
After removing the "retrieves(K)" call in the insert() method, the print runs just fine, so i am assuming there is an issues with the method "retrieves(K)", and since there is no error + cpu usage is higher, it might be an infinite loop, the problem is, i don't see it.
here is the method "retrieves(K)"
public Pair<Boolean, T> retrieve(K k) {
Pair<Boolean, T> ff = new Pair<Boolean, T>(false, null);
BSTMapNode<K, T> p = root;
if(root==null) {
return new Pair<Boolean,T>(false,null);
}
else
while (p != null) {
if (k.compareTo(p.key) == 0) {
ff.first=true;
ff.second=p.data;
return new Pair<Boolean,T>(true,p.data);
} else if (k.compareTo(p.key) < 0) {
p = p.left;
} else
p = p.right;
}
return new Pair<Boolean,T>(false,null);
}
EDIT: added insert method
public boolean insert(K k, T e) {
BSTMapNode<K, T> p = current;
BSTMapNode<K, T> q = current;
// ISSUE HERE
if (retrieve(k).first == true) {
current = q;
return false;
//
}
BSTMapNode<K, T> tmp = new BSTMapNode<K, T>(k, e);
if (root == null) {
root = current = tmp;
return true;
} else {
if (k.compareTo(current.key) < 0)
current.left = p;
else
current.right = p;
current = p;
return true;
}
The issue is with the insert() method. When it is called for the second time, root is non-null, so execution gets into the else branch. There, it sets current.left = p with current == p, so p is now its own p.left. When the retrieve() method arrives at that node, it sets p = p.left which changes nothing, causing the infinite loop.
Your approach using a current node does not work. In insert(), you have to search the insertion position of the new node from the root every time, similar to what you do in retrieve(). Just keep going down until you reach a leaf. Then insert the new node there.
The code could look like this:
public boolean insert (K key, T value) {
if (root == null) {
root = new BSTMapNode<>(key, value);
return true;
} else {
BSTMapNode<K, T> p = root;
while (true) {
if (key.compareTo(p.key) == 0) {
return false; // Already in BST
} else if (key.compareTo(p.key) < 0) {
if (p.left == null) {
p.left = new BSTMapNode<>(key, value);
return true;
} else {
p = p.left;
}
} else {
// Analogous for right sub-tree
}
}
}
}

delete odd numbers in queue

i am trying to delete odd numbers in the queue linked list but I am struggling to make function to
delete the odd here my code for better understanding ;
public class queueLinked {
private Node rear;
private Node front;
private int siz;
public boolean isEmpty() {//function return boolean if is empty or not
boolean response = false;
if (siz == 0) {
response = true;
}
return response;
}
public void enqueue(int element) { // inserting the value type of int
Node node = new Node(element);
if (front == null) {
rear = node;
front = node;
} else {
rear.setNext(node);
rear = node;
siz++;
}
}
public queueLinked() {
front = null;
rear = null;
siz = 0;
}
public Node dequeue() { // to remove the a element in the queue
Node response = null;
if (front != null) ;
if (front.getNext() != null) {
response = new Node(front.getData());
front = front.getNext();
siz--;
} else {
response = new Node(front.getData());
front = null;
rear = null;
}
return response;
}
public Node peak() {
Node response = null;
if (!isEmpty()) {
response = new Node(front.getData());
}
return response;
}
public int getSiz() { // to get the size
return siz;
}
public void display() { // display the queue function
System.out.print("\nQueue = ");
if (siz == 0) {
System.out.print("Empty\n");
return;
}
Node ptr = front;
while (ptr != rear.getNext()) {
System.out.print(ptr.getData() + " ");
ptr = ptr.getNext();
}
System.out.println();
}
public void deleteOdd() { // delete odd number in the queue
System.out.print("\nQueue = ");
if (siz == 0) { //make sure if it is empty or not
System.out.print("Empty\n");
return;
}
Node tempe = front;
if (front.getData() % 2 != 0){
enqueue(front.getData());
front = front.getNext();
rear = rear.getNext();
}
}
}
in function deleteOdd() i tried to make sure if is it empty and then I tried more than way to get the right one if the first one is odd delete it and front = front.next and I do not know if it is right
First, there are some issues in other methods in your code:
Issues
enqueue should also increase the size of the list when adding to an empty list.
dequeue should also decrease the size of the list when removing the last node from it.
dequeue has a wrong semi-colon after if (front != null) ; and so you can get a null pointer exception on the line below it.
Here is a possible correction with minimal changes:
public void enqueue(int element) {
Node node = new Node(element);
if (front == null) {
rear = node;
front = node;
} else {
rear.setNext(node);
rear = node;
}
siz++; // size should be updated in both cases
}
public Node dequeue() {
Node response = null;
if (front != null) { // correction of misplaced semi-colon
response = new Node(front.getData());
front = front.getNext();
if (front == null) {
rear = null;
}
siz--; // size should be updated in both cases
}
return response;
}
deleteOdd
I chose to only use public methods of the class, so that this function can be easily coded outside of the class, if desired.
The current size of the queue is used for a count down, so every node is visited exactly once. The nodes with even data are appended to the queue again, but this count down will prevent us from visiting those again (and again, ...):
public void deleteOdd() {
for (int count = getSiz(); count > 0; count--) {
Node node = dequeue();
if (node.getData() % 2 == 0) {
enqueue(node.getData());
}
}
}
Try the following function to delete odd number in queue.
public void deleteOdd() { // delete odd number in the queue
if (size == 0) { // make sure if it is empty or not
System.out.print("Empty\n");
return;
}
Node ptr = front;
while (ptr != rear.getNext()) {
if (ptr.getData() % 2 != 0) {
Node tmp = ptr.getNext();
ptr.data = tmp.getData();
ptr.next = tmp.next;
size--;
}
else
ptr = ptr.getNext();
}
System.out.println();
}
QueueLinked queue = new QueueLinked();
for (int i=1; i<=20; i++) {
queue.enqueue(i);
}
queue.display();
queue.deleteOdd();

Implementing remove() Iterator Method in Java

So I'm working with a generic LinkedList, and I need to be able to use an iterator to remove the second half of it. However, I can't seem to get it to work. Here's the iterator call:
Iterator<String> itr = seq.iterator();
for (int i = 0; i < N / 2; i++)
{
itr.next();
}
for (int i = 0; i < N / 2; i++)
{
itr.next();
itr.remove();
}
And here's my iterator methods:
boolean canRemove = false;
int previousLoc = -1;
Node<T> current = head;
#Override
public boolean hasNext()
{
return current != null;
}
#Override
public T next()
{
if (hasNext())
{
T data = current.getData();
current = current.getLink();
previousLoc++;
canRemove = true;
return data;
}
throw new NoSuchElementException();
}
public void remove()
{
if (!canRemove)
{
throw new IllegalStateException();
}
SortedLinkedList.this.remove(previousLoc);
canRemove = false;
}
It gives a NoSuchElementException on the itr.next() call under the second for loop. My best guess is it may have something to do with the way I determine the previous node's location; the class DOES have a getPrevious() method:
private Node<T> getPrevious(T entry)
{
Node<T> previous = null;
Node<T> traverse = head;
while (traverse != null)
{
//if(entry.compareTo((T) traverse.getData()) > 0)
if (traverse.getData().compareTo(entry) < 0)
{
previous = traverse;
traverse = traverse.getLink();
}
else
{
return previous;
}
}
return previous;
}
And a getPosition method:
public int getPosition(T anEntry)
{
Node<T> traverse = head;
for (int i = 0; i < manyNodes; i++, traverse = traverse.getLink())
{
if(anEntry.compareTo(traverse.getData()) == 0)
{
return i;
}
}
throw new IllegalArgumentException("Element not in list");
}
However, if I try something like
SortedLinkedList.this.remove(getPosition((T) getPrevious((T) current)));
I get "solution.Node cannot be cast to java.lang.Comparable"
Even though the class header does extend it:
public class SortedLinkedList<T extends Comparable<? super T>> implements Iterable<T>
EDIT: Here's the remove method:
public T remove(int givenPosition)
{
T dataToReturn;
if (givenPosition < 0 || givenPosition >= manyNodes)
{
return null;
}
if (givenPosition == 0)
{
dataToReturn = head.getData();
head = head.getLink();
}
else
{
Node<T> previous = head;
for (int i = 0; i < givenPosition - 1; i++)
{
previous = previous.getLink();
}
Node<T> oneToDelete = previous.getLink();
dataToReturn = oneToDelete.getData();
previous.setLink(oneToDelete.getLink());
oneToDelete.setLink(null);
}
manyNodes--;
return dataToReturn;
}
Try something like this:
public void remove()
{
if (!canRemove)
{
throw new IllegalStateException();
}
SortedLinkedList.this.remove(previousLoc--);
canRemove = false;
}
As in your loop the calls of next() incremented the previousLoc while the remove() method removed the item from the list, it did not changed the value of previousLoc. Thus the previousLockept incrementing, while all elements were to be removed.
To see this in work, you should print out previousLoc during next() and remove()...

Deleting a node at a given index in Java; What am I doing wrong?

I have been stuck for the last 40-so minutes on this problem. I'm unsure of what I am doing wrong here, I have tried debugging many times and have read similar Q/A's. Can't figure it out and my assignment is due at midnight.
It is not deleting the Node.. None at all in fact. If the code seems right, then the problem may be lying inside main. Let me know, please & thank you!
Any help is well appreciated! :)
Problem Method Below
void deleteAtIndex(int idx)
{
if (length() >= idx)
{
if(idx == 0)
{
head = head.getNext();
}
else
{
Node temp = findAtIndex(idx-1);
temp.setNext(temp.getNext().getNext());
}
}
else
System.out.println("Invalid position");
}
Full Class Code Below
public class ShapeLinkedList {
public Node head; // Head is first node in linked list
public ShapeLinkedList() { }
public ShapeLinkedList(Node head) {
}
public boolean isEmpty() {
return length() == 0;
}
public void insertAtEnd(Shape data) {
Node end = new Node(data, null);
if (head == null)
head.setNext(end);
else
tail().setNext(end);
}
public void insertAtBeginning(Shape data) {
if (data != null)
{
Node temp = new Node(data, head);
head = temp;
}
}
public Node tail() {
if (head == null){
return null;
}
else
{
Node temp = head;
while(temp.getNext() != null){
temp = temp.getNext();
}
return temp;
}
}
public int length() { // 1
Node temp = head;
if (temp == null)
return 0;
int tempIndex = 0;
while(temp.getNext() != null){
temp = temp.getNext();
tempIndex++;
}
return tempIndex;
}
void insertAtIndex(int idx, Shape data) { //3
if (length() >= idx)
{
Node current = new Node(data, null);
Node temp = findAtIndex(idx);
current.setNext(temp.getNext());
temp.setNext(current);
}
}
Node findAtIndex(int idx) { // 2
if (length() >= idx)
{
Node temp = head;
for(int i = 0; i < idx; i++)
{
temp = temp.getNext();
}
return temp;
}
else
return null;
}
void deleteAtIndex(int idx) { //4
if (length() >= idx)
{
if(idx == 0)
{
head = head.getNext();
}
else
{
Node temp = findAtIndex(idx-1);
temp.setNext(temp.getNext().getNext());
}
}
else
System.out.println("Invalid position");
}
#Override
public String toString() {
return "";
}
void deleteData(Shape s) {
Node temp = head;
for(int i = 0; i < length(); i++)
{
if(temp.getData() == s)
deleteAtIndex(i);
}
}
#Override
public int hashCode() {
return 0;
}
#Override
public boolean equals(Object obj) {
return false;
}
// Node is nested class because it only exists along with linked list
public static class Node {
private Shape data;
private Node next;
public Node(Shape S, Node N){
data = S;
next = N;
}
public Node getNext(){
return next;
}
public Shape getData() { return data; }
public void setNext(Node N) { next = N; }
// TODO develop all the methods that are needed
// such as constructors, setters, getters
// toString, equals, hashCode
}
}
You have multiple bugs in your class. I guess if you fix them, your code will work fine. SO is not a debugging platform, thus your question is off-topic and you should learn using a debugger.
Here some issues I instantly have seen from a quick look at your code, I'm sure there are more issues:
if (length() >= idx) should probably be if (length() > idx) at all places and
if (head == null) head.setNext(end); should probably be if (head == null) head = end; and
public ShapeLinkedList(Node head) { } should probably be public ShapeLinkedList(Node head) { this.head = head; } and
int tempIndex = 0 should probably be int tempIndex = 1

Remove method on the doubly list not returning the correct value

Here is my code:
public class RecipeBook {
private class Node {
private Recipe mData;
private Node mNext;
private Node mPrev;
public Node(Recipe data, Node next, Node prev) {
mData = data;
mNext = next;
mPrev = prev;
}
}
private Node mHead;
private Node mTail;
private int mCount;
public RecipeBook() {
}
public void add(Recipe itemToAdd) {
Node newNode = new Node(itemToAdd, null, null);
if (mHead == null)
mHead = mTail = newNode;
else {
mTail.mNext = newNode;
newNode.mPrev = mTail;
mTail = newNode;
}
mCount++;
}
public int getCount() {
return mCount;
}
public Recipe get(int index) {
Node n = mHead;
for (int i = 0; i < index; i++) {
if (n == null)
return null;
n = n.mNext;
}
return n != null ? n.mData : null;
}
public boolean remove(Recipe itemToRemove) {
Node n = mHead;
boolean check = false;
if (n == null) {
check = false;
return check;
}
while (n != null) {
if (n.mData == itemToRemove) {
if (n == mHead) {
mHead = mHead.mNext;
mHead.mPrev = null;
}
else if (n == mTail) {
mTail = mTail.mPrev;
mTail.mNext = null;
}
else {
Node prev = n.mPrev;
Node next = n.mNext;
prev.mNext = next;
next.mPrev = prev;
}
check = true;
mCount--;
return check;
}
else {
n = n.mNext;
}
}
return check;
}
public Recipe searchByName(String name) {
for (int i = 0; i < this.getCount(); i++) {
if (this.get(i).getName().equals(name))
return this.get(i);
}
return null;
}
public Recipe searchByIngredients(String target) {
for (int i = 0; i < this.getCount(); i++) {
if (this.get(i).hasIngredients(target) == true)
return this.get(i);
}
return null;
}
}
My problem is with the remove method, and I've actually checked with the debugger. The while loop works fine, and the program goes through the if statement when n.mData == itemToRemove. It removes what it's suppose to remove, no matter where the item is in the list. In addition the mCount gets smaller by one, and check becomes true, but once it gets to return it doesn't return anything. Instead it goes back to the loop, and keeps going until n is null. This would have been fine if check was remaining true, but after it goes out of the if statement without returning anything, it reverts check back to false which then makes the whole method return false. I've tried removing the return and having break which gave me the same result. I've also tried not having a return nor break while running the debugger which showed that it remained in the if statement, as if that statement was a loop.
This is a temporary solution, but try adding a break after when n.mData == itemToRemove, then return check. This should be able to give you some hints perhaps as to why your code isn't working.
public boolean remove(Recipe itemToRemove) {
Node n = mHead;
boolean check = false;
if (n == null) {
check = false;
return check;
}
while (n != null) {
if (n.mData == itemToRemove) {
if (n == mHead) {
mHead = mHead.mNext;
mHead.mPrev = null;
}
else if (n == mTail) {
mTail = mTail.mPrev;
mTail.mNext = null;
}
else {
Node prev = n.mPrev;
Node next = n.mNext;
prev.mNext = next;
next.mPrev = prev;
}
check = true;
mCount--;
break;
}
else {
n = n.mNext;
}
}
return check;
}

Categories