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).
Related
I am creating a double-linked list (has a previous and next pointer) from scratch using nodes. I'm trying to write the methods to implement a ListIterator and I'm having trouble figuring out how to write the remove method. I know it is probably something really simple but I don't have a lot of experience with iterators and I can't find a tutorial or post on this anywhere.
private Node<E> cur;
private Node<E> head;
public E next() {
if(size == 0) throw new NoSuchElementException();
if(cur.next == null) throw new NoSuchElementException();
return cur.next.value;
}
public boolean hasNext() {
boolean flag = cur != null;
return flag;
}
public void remove() {
//??????????????????
}
To delete a node, the prev node needs to point to next node, and vice versa (respective to current) . That's it. Pretty simple.
Edge cases to consider:
Deleting head node
Deleting tail node
Deleting last remaining node
I hope this is enough for you to code it yourself.
I am trying to create a method that reverses a Linked List. I have a class that creates a linked list
public class LinkedList<t> {
public class Node {
t item;
Node next;
}
private Node firstNode;
public Node getFirstNode() { return this.firstNode; }
public void appendToTail(t item){
if(this.firstNode == null){
this.firstNode = new Node();
this.firstNode.item = item;
return;
}
Node current = this.firstNode;
while(current.next != null){
current = current.next;
}
current.next = new Node();
current.next.item = item;
}
}
The method for reversing the linked list is in my "Main" class
public static LinkedList reverseLinkedList(LinkedList<Integer> l){
LinkedList.Node current = l.getFirstNode();
LinkedList<Integer> reverse = new LinkedList<Integer>();
LinkedList.Node head = reverse.getFirstNode();
while(current != null){
LinkedList.Node newHead = new reverse.Node();
newHead.item = current.item;
newHead.next = head;
head = newHead;
current = current.next;
}
return reverse;
}
For every new node that I want to add in the front of my new reversed linked list I need to create a new instance of "Node" class which enclosed inside the "LinkedList" class. "Node" class cannot be static since its "item" attribute is set to the same generic type from "LinkedList" type. So, I need a instance of the class "LinkedList" so that I can access "Node" class and create its object. In the above code I have used the "reverse" instance on "LinkedList" to do exactly that. But I get an error saying "Package reverse does not exist". This must be because I am trying to use it as a package. How may I solve this issue?
I must be able to solve this issue by separating "Node" class from "LinkedList". Is there anyway else I can do so without doing that?
Update this line:
LinkedList.Node newHead = new reverse.Node();
, To be
LinkedList.Node newHead = reverse.new Node();
If the requirement is only to reverse linkedlist, use Collections.reverse method which takes a list as a parameter and returns the reversed list.
I'm not seeing a problem with creating Node as static. Does doing it this way fix the problem? I've changed the type parameter names to make it more clear what is being declared and when an existing type parameter is being reused.
public class TestList<T> {
private Node<T> head;
private static class Node<X> {
X element;
Node<X> next;
}
public void add( T element ) {
Node<T> node = new Node<T>();
node.element = element;
if( head != null )
node.next = head;
head = node;
}
public T get() {
return head.element;
}
}
class External {
public static <Z> void reverse( TestList<Z> arg ) {
TestList.Node<Z> temp = new TestList.Node<>();
temp.element = arg.get();
// etc.
}
}
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;
}
}
I have the following Node class used to implement linked list:
class Node {
Node next = null;
int data;
public Node (int d) {
data = d;
}
void AppendToTail (int d) {
Node end = new Node(d);
Node current = this;
while (current.next != null) {
current = current.next;
}
current.next = end;
}
}
And I want to create a method that given a Node, it will delete it from a Linked list. So, I know how to create a function like this. But I am unsure how would I make it fit in my class.
Node deleteNode(Node head, Node toDelete) {
Node n = head;
if (n.data == toDelete.data) {
return head.next;
}
while (n.next != null) {
if (n.next.data == toDelete.data) {
n.next = n.next.next;
return head;
}
n = n.next;
}
return head;
}
However, I am failing to see how would I put that into my Node class. Any suggestions?
Make the function a static function in the Node class.
A problem I see would be you not putting the append and delete functions into the linked list class rather than in the node class. You should have the node class be totally separate from the linked list class. Therefore you can have the append and delete methods in the linked list class that add and delete instances of your node class. This helps you because then you don't have to worry about the node class one its created, you can just focus on the implementation in the linked list class.
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.