Remove duplicate elements from a linked list - java

I was trying to read a program of removing duplicate elements in a linked list. I am confused about the break conditions put in the while loop. Below is the code.
public static <T> void removeDuplicates(SinglyLinkedList<T> list) {
SinglyLinkedList<T>.Node current = list.headNode; // will be used for outer loop
SinglyLinkedList<T>.Node compare = null; // will be used for inner loop
while ( current != null && current.nextNode != null) {
compare = current;
while (compare.nextNode != null) {
if (current.data.equals(compare.nextNode.data)) { //check if duplicate
compare.nextNode = compare.nextNode.nextNode;
} else {
compare = compare.nextNode;
}
}
current = current.nextNode;
}
}
The statement while ( current != null && current.nextNode != null) is confusing to me. If I remove current != null from the statement the output is produced same. Suppose the list is 1 -> 2 -> 3 -> null. Now initially current is at 1 , then if we traverse the list and when current points to 3 , at that moment (current.nextNode == null) and if I use only while( current.nextNode != null , that does the job for me. Then why the author has used current != null. Please help me clear the confusion.

A completely empty list would have current be null. The dot is the dereference operator - dereferencing null causes a NullPointerException. Hence, calling that method with an empty list would cause an NPE whereas the correct action is to do nothing ('remove all duplicates from this empty list' is a job that can be done, and it is done by doing nothing - there are no duplicates in an empty list, thus, nothing to remove).
For a non-empty list, indeed, that part of the while clause is never going to be relevant. Given that it would never get there (the last node in the list would already fail the while clause due to having a current.nextNode of null).

Related

Remove All Occurrences of a Given Value from a Doubly Linked List

Alright, so cut a long story short, what I'm trying to do here is remove all instances of value e from a doubly linked list. As far as I know, my logic is at least mostly right, but for some off reason it isn't actually removing any of the nodes in my test cases.
public boolean removeAll(int e) {
DIntNode dummy = head,next = null;
if (head == null)
return false;
while (dummy != null) {
if (dummy.getData() == e) {
next = dummy.getNext();
dummy.getNext().setPrev(null);
dummy = next;
return true;
}
else
dummy = dummy.getNext();
}
return false;
}
This is what I currently have for my code of the metho. My logic here was to use a dummy DIntNode that starts at the head and a "next" node to help me shrink the list, so to speak. In other words, if the list was something like "1<-> 1 <-> 2 <-> 3", the function would change it to "2<->3", in theory. The reason this is a boolean function is because I'm required to return true if the given value is removed form the list.
Is there just another step in the logic that I'm missing, or is the methodology itself just unreliable? I'm very unsure at this point, so any and all help would be greatly appreciated.
You set
dummy.getNext().setPrev(null);
But previous node also have reference to next node you try to remove. You should set this reference to next active value.
That because when you want to get all linked list previous value still know about node you remove, because of next node reference
You can try with the following code:
if (dummy.getData() == e) {
DIntNode temp = dummy.getPrevious();
temp.next = dummy.getNext();
temp = dummy.getNext();
temp.previous = dummy.getPrevious();
return true;
}
This used the previous reference. So the previous node will now have reference to the next node of your dummy node (node to be deleted). And similarly, the next node of dummy node will have reference of previous node of your dummy node. So, the dummy node will loose its connection/link from its doubly link list and that's what we want!
Please try.
Two issues with the code:
When relinking a doubly linked list, where removing B from A - B - C, you need to set the next node for A to be C as well as the previous node for C to be A. With trying to keep you method names:
A.setNext(current.getNext());
C.setNext(current.getPrev());
With your code, if you find an occurrence, you return, which means that no other instances will be removed since you jump out of that method. You will probably need a new boolean removed variable, that is set to false, return true changed to removed = true and return false changed to return removed.
The method exits after the first encounter of 'e'.
If you want to remove all instances of 'e', then you should have something like this:
boolean listChanged = false;
while (dummy != null) {
if (dummy.getData() == e) {
// update list
...
listChanged = true;
}
...
}
return listChanged;
Also, you should not write your code like this:
dummy.getNext().setPrev(...); // throws NPE if next is null

Linked List NullPointerException Java

In LinkedList we normally assign null value to last node and also use this condition to check for the last node.
I am checking for the last node with the same condition either its "next" node link is null or not. But I'm unable to handle NullPointerException when I get null value by the method "getNext".
while(lastNode.getNext() != null)
{
lastNode= lastNode.getNext();
}
I assume this is a custom implementation of a LinkedList; java.util.LinkedList does not have a getNext() method.
That said, what you want is:
while (current != null) {
past = current;
current = current.getNext();
}
return past;
I am assuming here that you want to return the last node, and that past is a variable of the same type as current.

NullPointerException in a while loop using a Binary Tree node

I am using a binary tree structure here. I am getting a "NullPointerException" from the line containing the while statement. I am completely confused about why that would be.
BinaryTreeNode<CharData> currNode = theTree.findValue(data);
// Move up the Binary Tree to create code.
while(currNode.getParent() != null) {
// The loop does some stuff that doesn't
// affect what is assigned to currNode.
// Move to the parent node for the next iteration.
currNode = currNode.getParent();
} // End the while loop.
return code; // Return the string of binary code.
Find value is a method from my BinaryTree class that searches for and finds the node containing specific data. I know this works from testing it separately outside of this implementation.
The only reason why the while-loop statement can throw a NPE is, when currNode is null. I suspect findValue() returned null.
I guess one fix (when you care about the topmost node) would be:
while(currentNode != null) {
rootNode = currentNode;
currentNode = currentNode.getParent();
}
Or the typical pattern which relies on boolean shortcut evaluation:
while(curentNode != null && currentNode.getParent() != null)
Or my prefered solution using guards:
if (currentNode == null)
throw NotFound(); // or return something
while(curentNode.getParent() != null) {
If you see the code:
BinaryTreeNode<CharData> currNode = theTree.findValue(data);
I guess, currNode is getting some value if findValue() able to search data else it is returning NULL values.
When it returns a NULL value it will throw NPE.
To avoid it, you can modify your code a little bit.
while(currNode != null && currNode.getParent != null) {
// your code here
}

Setting myself to null - Java

I came across the following problem:
Delete a node in the middle of a singly linked list, given only access to that node. (head is not given)
Now there are a lot of solutions and they all do not work when the element to be deleted is the last node.
Why wouldn't this work?
public static void removeNode (Node n){
if(n.next == null){ //n is the last node
n= null;
return;
}
//handling general case here
}
Java passes parameters by value, so setting n to null has no effect outside of the method. This means the method essentially does nothing when passed the last node of a list.
You need to set null the reference in the previous node, not the variable that references to your last node, something like this:
if(n.next == null) {
prev.next = null;
return;
}
n is local to the method, so changing its value won't affect the list itself. You need to modify the next of the previous node, which you do not have access to.

Comparator in Linked Lists

I'm writing a program that is a linked list, trying to insert something in order and I've used this in my code but it keeps saying that it's a NullPointerException, and I'm not sure why.
public SortedLinkedList<T> add(T element) {
Node insert = new Node(element);
Then I check to make sure curr isn't null.
if (comparator.compare(curr.data, insert.data) <= 0
&& comparator.compare(curr.next.data, insert.data) > 0){
Then I check to make sure curr isn't null.
The code you've posted isn't checking to see if curr is null, it is doing a comparison, and probably trying to do a comparison on an Object that does not exist.
You should check to make sure that the next element (curr.next) in your linked list exists before you try to access it.
I dont't know what's the body of comparator.compare, but it there's no null check in that method, you should do something like this.
if (curr != null && curr.data!=null && comparator.compare(curr.data, insert.data) <= 0
&& comparator.compare(curr.next.data, insert.data) > 0){

Categories