Hello I'm learning singly linked list and I'm using an example from a java book, I'm trying to delete a node given an string value. I already coded but i doesnt delete anything, anyone can give me any advice? Im already frustrated because I dont know what Im doing wrong. Thanks.
public class LinkedStringLog implements StringLogInterface {
protected LLStringNode log; // reference to first node of linked
// list that holds the StringLog strings
protected String name; // name of this StringLog
public LinkedStringLog(String name)
// Instantiates and returns a reference to an empty StringLog object
// with name "name".
{
log = null;
this.name = name;
}
public void remove(String element){
LLStringNode currentNode;
LLStringNode temporal;
currentNode = log;
temporal = currentNode.getLink();
if(element.equalsIgnoreCase(currentNode.getInfo())){
log = currentNode.getLink();
}
while(currentNode!=null){
if(element.equalsIgnoreCase(currentNode.getInfo())){
temporal.setLink(currentNode.getLink());
}
else{
currentNode.getLink();
temporal = currentNode;
}
}
I guess you're entering in a infinite loop, because you're not updating currentNode variable in the while loop.
You may want something like this:
while(currentNode!=null){
if(element.equalsIgnoreCase(currentNode.getInfo())){
//don't you want to update the link of the node before currentNode here?
}
else{
currentNode = temporal; //update currentNode variable
temporal = currentNode.getLink(); //update temporal variable
}
}
You seem to have many errors.
One of the main issues was that you failed to maintain a prevNode reference as you traverse the linked list, so you were not able to keep all the items in the list linked together.
Also, where do you set log to the head item of the linked list?
In any case, this version of remove might work better (as long as log is actually non-null):
public void remove(String element) {
if (log == null) {
return;
}
LLStringNode currentNode = log;
LLStringNode prevNode = null;
while (currentNode != null) {
LLStringNode nextNode = currentNode.getLink();
if (element.equalsIgnoreCase(currentNode.getInfo())) {
if (currentNode.equals(log)) {
log = nextNode;
}
if (prevNode != null) {
prevNode.setLink(nextNode);
}
} else {
prevNode = currentNode;
}
currentNode = nextNode;
}
}
Related
I am a beginner of programming. I have been searching for solving the null pointer exception. The null pointer exception happens because the object has not been initialised. However it happens when I implement a code for enqueuing the data of an object into a queue although I have initialised the object.
The below is the code for the enqueue
public void addToList(Human human){
//When the list is empty, insert the human data
if(isEmpty()){
Node temp = new Node(human);
temp.setNext(this.head);
this.head = temp;
numNodes++;
}
else{
Node current = this.head;
//If the list is not empty, the new human data will be enqueued based on the priority
//If the current data has a lower priority, temp data (new human) will be inserted into the queue first
if(current.getHuman().getPriority() < temp.getHuman().getPriority()){
temp.setNext(this.head);
this.head = temp;
numNodes++;
}
else{
//If the current data has a higher priority , it will traverse the queue until there is space(current.next = null) for temp data to insert
while (current.getNext() != null){
current = current.getNext();
}
current.setNext(temp);
temp = this.head;
//temp.setNext(this.head);
numNodes++;
}
}
}
Regardless of the priority, even if I delete the code for priority, I cannot run the enqueue method after the file is compiled.
It shows me the below null pointer exception.
java.lang.NullPointerException: Cannot invoke "Node.setNext(Node)" because "<local2>" is null
The Node class is as below:
public class Node{
protected Node next;
protected Human human;
public Node(Human new_human){
this.human= new_human;
this.next = null;
}
public Node getNext(){
return next;
}
public void setNext(Node new_next){
this.next = new_next;
}
public Patient getHuman(){
return human;
}
public void setHuman(Human hu){
this.human= hu;
}
}
Did I do something wrong ? I have searched for solutions but still have not fixed. The potential problem should be the "temp.setNext(this.head)", but if I have already made "Node temp = new Node(human)", there should not be null. I wonder if my initialisation is incorrect. I have tried "this.head = new Node(human)" but still did not work.
Hope anyone can give me some advice to fix this problem.
Thank you very much.
When I call this insert before method, it does what it is supposed to do at first, but then it causes the linked list to keep going on and on forever until i click stop (with system out print). I can't find where it goes wrong in this method
private boolean insertBefore(Node aNode, Node beforeNode)
{
Node currentNode;
Node prevNode;
//aNode= new Node();
currentNode = this.getHead();
while(currentNode!=null && currentNode.getNext()!=aNode)
{
if(currentNode == beforeNode)
{
prevNode = this.getPrevious(beforeNode);
prevNode.setNext(aNode);
aNode.setNext(beforeNode);
//aNode.setNext(currentNode);
return true;
}
currentNode = currentNode.getNext();
}
currentNode.setNext(beforeNode);
return false;
}
This is much simpler than the code specified above, given you have a doubly-linked list there is no need to loop over all the elements:
private boolean insertBefore(Node aNode, Node beforeNode) {
if(beforeNode.getPrevious() != null) {
beforeNode.getPrevious().setNext(aNode);
aNode.setPrevious(beforeNode);
} else {
head = aNode;
}
aNode.setNext(beforeNode);
beforeNode.setPrevious(aNode);
}
If the beforeNode is at the head of the list, your new node becomes the head.
Otherwise, there is a node behind your beforeNode. This must now point at your new node.
Either way, your new node's next pointer points at the beforeNode node.
My CS professor asked us to develop our own Java program using circular linked lists. My project is to add or delete names (of type String) from a circular list. So far, my add methods work perfectly; however, my removeNode() method does not work and does not remove the desired element. It also goes on an infinite loop and I have tried so many pieces of code and neither of them work.
My remove method is the following:
public E removeNode(E nodeToBeDeleted)
{
Node<E> nodeFound = findNode(nodeToBeDeleted);
if(nodeFound != null)
{
nodeFound.prev.next = nodeFound.next;
nodeFound.next.prev = nodeFound.prev;
size--;
return nodeFound.data;
}
return null;
}
basically, the findNode() searches for the node whose data is equal to the String plugged in as a parameter, but when I call the outputList() method, which returns a String representation of the current nodes on screen, it goes on infinite loop.
The outputList method is:
public void outputList()
{
Node<E> position = head;
do
{
System.out.print(position.data + " ==> ");
position = position.next;
} while((position != null) && (position.next != position));
}
Any help would be highly appreciated.. Thanks in advance.
The Node class is:
static class Node<E> {
/** The data value. */
private E data;
/** The link to the next node. */
private Node<E> next = null;
/** The link to the previous node. */
private Node<E> prev = null;
private Node(E dataItem) {
data = dataItem;
}
private Node(E newData, Node<E> nodeRef)
{
data = newData;
next = nodeRef;
}
private Node(Node<E> prevRef, E newData)
{
data = newData;
prev = prevRef;
}
//set next link
private Node(Node<E> newData, Node<E> nodeRef)
{
data = (E) newData;
next = nodeRef;
}
} //end class Node
while((position != null) && (position.next != position))
This should really be:
while((position != null) && (position.next != head))
Imagine if you have a singleton - the absolute base case for traversal. head and position will both be pointing to it when you start, and when you wish to advance, position will refer to the same place as head once again. This will continue ad infinitum.
The iteration must stop when you've reached your starting point once again.
while(position.next != head)
I think checking above condition is enough for Doubly Circular LinkedList.
Hi I am making a linked list data structure and within the list I define an iterator inner class. I am currently having trouble with the remove method. The functionality that I want is that it cannot be called on the if the next has not been called or the current element in the list has been removed already. Here's what I have.
private class ListItr implements java.util.Iterator<E>{
private Node<E> currentNode;
private Node<E> nextNode;
private Node<E> previousNode;
public ListItr(List<E> theList){
previousNode = new Node<E>(null);
currentNode = new Node<E>(null);
nextNode = theList.head;
currentNode.setSuccessor(nextNode);
}
public boolean hasNext(){
return nextNode != null;
}
public E next(){
if(nextNode == null)
throw new NoSuchElementException();
previousNode = currentNode;
currentNode = nextNode;
nextNode = nextNode.getSuccessor();
return currentNode.getElement();
}
public void remove(){
if(currentNode == null)
throw new IllegalStateException();
nextNode = currentNode.getSuccessor();
previousNode.setSuccessor(nextNode);
currentNode = null;
size--;
}
}
As you can see this will successfully remove the node in the list by splicing around it, setting the current node to null. However if it is called on the first without calling next, it will still run when I do not want it to. I can hack around it by adding a flag nextNotCalled, setting it to true in the constructor, then setting it false when next is called however I feel that that is not the way to go about it...
If the question is in general how to do it, I'd look at how Josh Bloch and Neil Gafter did it. Look at the class definition for Itr (line 330).
I am trying to make an add method for a linked list, but for some reason (that is not obvious to me, in fact I came here to get help finding the error) it goes into an infinite loop every time.
EDIT: I found the error, and I will keep my original code with a comment with the corrected code
public void insert(String majorName)
{
MajorNode newNode = new MajorNode(majorName, 1);
boolean inList = false;
MajorNode current = first;
if(isEmpty())
{
first = newNode;
// inList = true;
}
else
{
while(current.next != null)
{
if(current.majorName.equalsIgnoreCase(majorName))
{
current.frequency++;
inList = true;
break;
}
else
{
current = current.next;
}
}
}
if(!inList)
{
newNode.next = first;
first = newNode;
}
}
Here is my node class if it is needed:
public class MajorNode
{
public String majorName;
public int frequency;
public MajorNode next;
public MajorNode(String majorName, int frequency)
{
this.majorName = majorName;
this.frequency = frequency;
}
public String toString()
{
return majorName + " " + frequency;
}
}
On the first call to insert(), one assumes isEmpty() returns true and consequently first is set to the newNode before newNode's next field is set to the previous (null) value of first. Thus, when the list is non-empty, the loop iterates indefinitely on the last element in the list whose next field points to itself.
Out of curiosity, why are you trying to implement your own linked list functionality rather than build upon available packages (such as java.util.LinkedList<E>)?
When you create the first node you do this:
if(!inList)
{
newNode.next = first;
first = newNode;
}
This points the first nodes next at itself... hence a loop
You should be leaving the newNode.next as null for the first node, so that when you insert the second item, you reach the end of the chain..
You will have an wrong frequency if you add a node which is similar to the last node of your List. Consider this situation (adding 2 similar nodes in the empty list)
You will add a node1 in a blank list. So first & current will point to node1. (but node1.next will be null)
If you add the same node (or a node with a same majorName), you will reach to while loop (because List is not empty now). And also, you will not enter into a while loop as well. (as your current.next is still null)
and you will end up with two noes with same majorName in your list.
I would suggest to use
while(current != null)
instead of
while(current.next != null)