Add method for custom LinkedList class - java

I have been working on this add method for a custom linkedlist lab I am working on. I cannot figure out how to shift values over by one index, once I insert the new node. Here is my source code.
public void add(int index, Object element) throws IndexOutOfBoundsException {
if(index > size() || index < 0) {
throw new IndexOutOfBoundsException();
}
ListNode newNode = new ListNode(element, null);
if(head == null) {
head = newNode;
return;
}
ListNode nextNode = head.nextNode;
ListNode currNode = head;
int i = 0;
while(currNode!= null) {
if(index == i) {
break;
}
currNode = nextNode;
//Breaks down here with null pointer exception
nextNode = nextNode.nextNode;
}
currNode = newNode;
currNode.nextNode = nextNode;
}

It is throwing null pointer as when you are iterating last node, next node points to null. Check for next node point to null also if you have to add new node in last.
Also in your code you are not increasing the value of i always it is iterating the whole list.

I don't really know what you are trying to achieve here, and I agree with #Pritam Banerjee's comment. But an obvious problem in your code is that you are never incrementing i, so you'll never break out of your while loop and at some point you are going to hit the end of your list and nextNode.nextNode is going to be null, hence your exception. (Also note that nextNode.nextNode will be null before currNode is.)

Related

Why can't I reverse a linked list in this way without getting a null pointer exception?

this is my first question here. This may be a dumb question but I am having issues with understanding why the order specifically matters when reversing a linked list in this way.
So here I'm reversing a linked list, which works
ListNode prev = null, curr = head, next = head;
while (curr != null){
next = next.next;
curr.next = prev;
prev = curr;
curr = next;
}
head = prev;
return head;
which works just fine.
But why can't I do the following?
//edge cases:
if (head == null || head.next == null){
return head;
}
ListNode prev = null, curr = head, next = head.next; //change here
while (curr != null){
//line was previously here
curr.next = prev;
prev = curr;
curr = next;
next = next.next; //moved here
}
head = prev;
return head;
Why does it matter that I set next = next.next at the beginning of the while loop, rather than the end? Why can't I set next = head.next first and then iterate it at the end of the loop without getting a null pointer exception?
Just for the record, you can think of the reverse operation as popping from the input list and pushing onto the result. Less epic code results:
ListNode reverse(ListNode head) {
ListNode result = null;
while (head != null) {
ListNode elt = head; // pop into elt
head = head.next;
elt.next = result; // push elt onto result
result = elt;
}
return result;
}
When you make such a change, you change the state at which the loop condition will be verified. And this causes the issue.
In the working code, we have this loop invariant:
curr and next are equal. They are either both null or both reference the same node.
In the non-working code, this is not true, as now next is one step ahead. The corresponding loop invariant is now next == curr.next. So when curr is the tail node, next will be null. In the next iteration of the loop, next = next.next is executed, which is invalid as next was null, so this raises an exception.
It would work if you would make that statement conditional:
if (next != null) next = next.next;
Or this would also work:
if (next == null) break;
next = next.next;
But both these alternatives are not as elegant as the original code, as now there are two checks to be made in each iteration (the loop condition, and this extra check). In fact, this extra check is just the repetition of the loop condition as at that moment next and curr are equal.

Delete a node from Singly Linked list at any index using a single method/function in java

I want to create and delete a node from the singly linked list in java. The deleting method will take the index of node and delete that node.
The logic is working but it is not deleting the node at first index (0) how do i modify this code so that it can delete node at any position without using extra loops. I know that I am using starting index as 1 in code but I can not riddle this that if entered index is zero then how the program can delete the "previousNode" using the same loop. It will require another loop (based on this logic). Is there a way to remove this extra loop
public E deleteNode(int t) throws IndexOutOfBoundsException{
if(size==0)
return null;
if(t>=size)
throw new IndexOutOfBoundsException("Invalid Input");
Node<E> previousNode=head;
Node<E> currentNode=previousNode.getNext();
int currentIndex=1;
while(currentIndex<t){
previousNode=previousNode.getNext();
currentNode=previousNode.getNext();
currentIndex++;
}
previousNode.setNext(currentNode.getNext());
size--;
return currentNode.getElement();
}
If user enters the index 0, then the output of {1,2,3,4} should be {2,3,4} but I get {1,3,4}.
One option would be to handle it as a special case as it requires updating head.
if (t == 0) {
head = head.getNext();
}
//rest of your code..
Node<E> previousNode=head;
//...
Or, you can do like
Node<E> previousNode = null;
Node<E> currentNode = head;
int currentIndex = 0;
while(currentIndex < t) {
previousNode = currentNode;
currentNode = currentNode.getNext();
currentIndex++;
}
if (previousNode == null) { //removing first node
head = head.getNext();
} else {
previousNode.setNext(currentNode.getNext());
}
size--;
return currentNode.getElement();
But anyway you need to handle it as a special case.

Why can't I remove occurrences in the linked list?

Problem: Given a value, remove all instances of that value from a linked list. More info below: JAVA
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode n = head; //1, 2, 6, 3, 4, 5, 6
while(n.next == null){
if(n.next.val == val){
n.next = n.next.next;
}
n = n.next;
if(n == null){break;}
}
return head;
}
}
Since its a pass by reference, it should be updating shouldn't it?
I tried:
removeElements([1,2,6,3,4,5,6], 6)
But it didn't remove anything. So what I am doing incorrectly?
There are a couple of issues:
you want to loop until a node is null not until is not null (i.e. while( ... != null))
you might want to loop until n is null, not until n.next is null, otherwise you'd skip the last element
you want to check for n.val == val not n.next.val == val, otherwise you'd skip the first element
if you check n you want to keep track of the previous node in case you need to remove n, i.e. prev.next = n.next.
if the first element (the head) is to be removed you need to replace the head, i.e. return the second element (this can be done by checking prev == null which would mean that n is the current head).
As mentioned by Thomas in his first point, you wrote the while loop incorrectly. Also, because you have a single linked list, you need to keep track of the previous node (also mentioned by Thomas).
public static ListNode removeElements(ListNode head, int val)
{
ListNode n = head;
ListNode prev = null; //the previous node.
while (n != null)
{
if (n.value == val)
{
//if prev is null it means that we have to delete the head
//and therefore we need to advance the head
if (prev == null)
{
head = n.next;
prev = null;//remains at null because there's nothing before head
n = head;//new head, let's start from here
} else
{
prev.next = n.next; //let's skip the element to delete
n = n.next;//let's advance to the next node
}
} else
{
//nothing to delete, let's advance to the next node and make
//the current node the previous node in the next iteration
prev = n;
n = n.next;
}
}
return head;
}
Its always a good practice to solve these questions with proper test cases. Design the possible test cases including the corner cases. Then follow your algorithm and see if it solves the problem for the test cases. Write the code and dry run it, this will do a sanity check of the code as well as of the logic.
Below are the cases for this question for which test cases must be written.
Null list,
List with one element and value being equal to the value to be deleted
List with one element and value not being equal to the value to be deleted
List with two elements and first node value being equal to the value to be deleted
List with two elements and last node value being equal to the value to be deleted
List with three elements and first node value being equal to the value to be deleted
List with three elements and second node value being equal to the value to be deleted
List with three elements and last node value being equal to the value to be deleted
Below is the code for the problem of removing nodes with a given value in a linked list.
public ListNode removeElements(ListNode head, int val) {
while(head != null && head.val == val){
head = head.next;
}
if(head == null){
return null;
}
ListNode node = head;
while(node.next != null){
if(node.next.val == val){
node.next = node.next.next;
}else{
node = node.next;
}
}
return head;
}

Bubble Sort in Double Linked List - Null Pointer Error

protected void sortHorseList(int iHorseCount)
{
int i = 0;
Horsie currentNode = head;
Horsie auxNode = new Horsie();
boolean foundChange = true;
while(foundChange)
{
foundChange = false;
for(i=0; i<iHorseCount-1; i++)
{
if (currentNode.getHorseValue() > currentNode.getNext().getHorseValue())
{
auxNode.setHorseValue(currentNode.getHorseValue());
currentNode.setHorseValue(currentNode.getNext().getHorseValue());
currentNode.getNext().setHorseValue(auxNode.getHorseValue());
foundChange = true;
}
currentNode = currentNode.getNext();
}
}
}
This code displays a null pointer error when running the main program. I am a novice at data structure, and I'm hoping to solve this problem with your help guys! Please teach me how to use bubble sort in a doubly linked list...HEEELP!
When you get to the end of the list, you aren't checking to see if a next element exists. Thus when you attempt to access it's value, you get the null reference exception. Your inner loop should look something like
Horsie currentNode = head;
Horsie nextNode = currentNode != null ? currentNode.getNext() : null;
while (currentNode != null && nextNode != null)
{
if (currentNode.getHorseValue() > nextNode.getHorseValue())
{
currentNode = Swap(head,currentNode,nextNode);
foundChange = true;
}
else
{
currentNode = nextNode;
}
nextNode = currentNode.getNext();
}
Where Swap(Horsie current, Horsie next) exchanges the place of current and next in the list and, optionally, updates the head if current was the head node.
I'll also note that you do want to swap the nodes in the list rather than swap the values between nodes unless you are sure that your list holds the only references to the node objects. If you don't you run the risk of having an object held by some other class unexpectedly mutate because you've changed its value during the sort.

Ordered LinkedList logic in Java, LinearNode head is being reassigned each time

I have a generic ordered Linked List class. For some reason, LinearNode head is being reassigned every single time I run add(). Any ideas? Why would head be changed each time I run this? I'm not even touching it. I can provide the other classes for testing, if needed.
public class myOrLiList<T extends Comparable<T>> {
public LinearNode head;
public int count;
public myOrLiList() {
head = null;
count = 0;
}
// LinearNode INNER CLASS
public class LinearNode {
public LinearNode next;
public T item;
public LinearNode(T thisitem) {
this.next = null;
this.item = thisitem;
}
}
public boolean isEmpty() {
return (head == null);
}
public void add(T thisItem) {
LinearNode newNode = new LinearNode(thisItem);
if (isEmpty()) {
head = newNode;
System.out.println("head filled!");
} else {
LinearNode compareNode = head;
do {
if (thisItem.compareTo(compareNode.item) < 0) {
newNode.next = compareNode;
break;
} else if ((thisItem.compareTo(compareNode.item) < 0)
|| (thisItem.compareTo(compareNode.item) == 0)) {
newNode.next = compareNode.next;
compareNode.next = newNode;
break;
} else {
compareNode = compareNode.next;
}
} while (compareNode.next != null);
}
System.out.println("Added!");
count++;
}
Thanks for your help.
The reason that your head is changing is because of this line:
compareNode = compareNode.next;
Earlier you did this:
LinearNode compareNode = head;
You're literally saying that compareNode IS your head object. You're setting the Object reference that points to head to also point to compareNode. Any actions you take on compareNode will affect head the exact same way.
Because you set compareNode = head, these two lines do the same thing to the same object reference:
compareNode.next = null;
head.next = null;
I see a couple of other things wrong. I'll try and go over them one by one.
Your logic for when the LinkedList is empty appears to be correct...
However,
if you add a second node when the list's size is 1, you're going to have some problems...
if (thisItem.compareTo(compareNode.item) < 0) you call this code and then break out:
newNode.next = compareNode;
break;
What are you doing with newNode after that? The answer is nothing. Since you didn't update head, nothing has changed. You created a LinearNode, set it's next value equal to the head, and then left it to die.
What I think you want to do is get a reference to the old node stored at head, save it, then set your head variable equal to your new node. Then you'll set newNode.next (where newNode is now head) equal to your OLD head node, which you saved. So you'll have something like this:
LinearNode oldHead = head;
head = newNode;
head.next = oldHead;
Now for the next part. You have an
if ((thisItem.compareTo(compareNode.item) < 0) || (thisItem.compareTo(compareNode.item) == 0))
You already covered the case where compareNode.item < 0, so why are you checking it again? It won't mess up your logic, but it's redundant.
Essentially, what you're trying to do is place your newNode before the current node if it compares to be < 0, place your newNode after the current node if it compares to be > 0, and either replace or do nothing if the currentElement ends up being == 0.
I've covered the < 0 case, so you should try and figure out how to do the greater than and equal cases.
While this class has some errors (Thanks for the tips, Michael!) the question I asked did not come from these errors.
In the new object class I had created for T, I had declared static properties. So, each time a new T thisItem was being created, all of the properties of all objects were being changed.

Categories