Descending ListNode Iterator Implementation - java

My goal in this method is to write the implementation for an iterator that iterates through elements of a listNode in descending order. (From the back to the front) I have attached my implementation of the ascending iterator. Any help in the right direction would be appreciated.
public MyDescendingDequeIterator(ListNode<E> back, ListNode<E> front) {
frontOfList = front;
nextToReturn = back;
while (nextToReturn.next != null) {
nextToReturn = nextToReturn.next;
}
}
public boolean hasNext() {
if (nextToReturn == null){
return false;
} else {
ListNode<E> current = frontOfList;
return true;
}
}
public E next() {
ListNode<E> current = frontOfList;
while ( current.next != nextToReturn ) {
current = current.next;
}
nextToReturn = current;
return nextToReturn.data;
}
public void remove() {
throw new UnsupportedOperationException();
}
}

Provided it's a regular ListNode implementation that has only next() method, you'll need to implement the prev() method - the hasNext in that case is quite similar to the one you've implemented already.
The other approach is to hold the start of the list and to iterate each time until next element will be nextToReturn (and then update nextToReturn). This is less desired approach since you'll need to iterate O(m^2) from end to start of list of length m;
UPDATE:
OK, first of all you don't need number of elements, since it's quite opposite to the Iterator idea.
So let's say we have
public MyDescendingDequeIterator(ListNode<E> back, ListNode<E> front) {
frontOfList = front;
nextToReturn = frontOfList;
current = frontOfList;
}
Next thing is than you want to set the nextToReturn = back (now you don't use back at all). And you don't really need two variables, since nextToReturn is the current iterator.
So it transforms to:
public MyDescendingDequeIterator(ListNode<E> back, ListNode<E> front) {
frontOfList = front;
nextToReturn = back;
}
Now let's look on the next() method
As I said you don't need an indexed for here, since you've got frontOfList that has a next attribute.
So it could be:
public E next() {
ListNode<E> current = frontOfList;
while ( current.next != nextToReturn ) {
current = current.next;
}
nextToReturn = current;
return nextToReturn.data;
}
hasNext implementation should be straightforward from here. Just pay attention that according to the good coding standards the method that starts with is or has rarely changes the state of the object.
Note, that I also omit possible null checks here and other possible specific checks as is just an example of direction.
UPDATE 2:
As I think of it now, you don't need the second parameter in the constructor either, just this:
public MyDescendingDequeIterator(ListNode<E> front) {
frontOfList = front;
nextToReturn = front;
// calculate back here instead of get it as param
while ( nextToReturn.next != null) {
nextToReturn = nextToReturn.next;
}
}
UPDATE 3:
Look, it won't help to just start writing some code and expect it to work, you should sit down first and start drawing the boxes with the arrows on the piece of paper and then try to understand what each function should do.
As I said before, your hasNext() method has a bug and incorrect in general. Why do you check the null? You move from back to front, do you have a null at some place at the front? What do you need the current object for. What does it do?
The next() method should check also if you're already at the first element. Otherwise it will (and it does ) cause NullPointerException at the last element.
Try to debug first, or at least add some printouts, it helps to understand where the bug is. But first you should build the algorythm, only then start coding it, not vice versa.

Related

Recursively delete the last occurrence in a linked list, Java

class Link{
private int value;
private Link next;
}
I am asked to write a recursive method to delete last occurrence of a certain value, say 4.
before 2->3->4->5->4->2
after 2->3->4->5->2
The last occurrence only. I know how to delete all occurrence but I can't tell if its the last occurrence. No helper method is allowed.
The one to delete all occurrence
public Link deleteAll(){
if (next == null){
return value==4? null:this;
}else{
if (value == 4){
return next.deleteAll();
}
next = next.deleteAll();
return this;
}
}
You can declare a pointer to the last occurred node and delete that node when reached the last element in list. Following steps explains that -
Declare two pointers one is next as in your above code another can be temp.
Iterate through list using next like you doing in deleteAll method above.
If you find the node you looking for assign that node to temp.In your case 4.
When next is null you reached the end of list now delete, whatever node is in temp delete that node. If temp is still null than no node found in given key.
EDIT:
Possible pseudo Code in case of recursion:
public void deleteLast(Node node,Node temp,Node prev, int data)
{
if(node==null)
{
if(temp!=null && temp.next.next!=null){
temp.next = temp.next.next;}
if(temp.next.next==null)
temp.next = null;
return;
}
if(node.data==data)
{
temp = prev;
}
prev = node;
deleteLast(node.next, temp, prev, int data);
}
Above code should be able to solve your problem. I made some edit in my approach which should be obvious from the code but let me describe it below
I added a prev pointer. Because if we want to delete a particular node we need to assign its next to prev node's next.So, we need the prev node not the node that we want to delete.
I think this change will follow in iterative approach too.
Not really answering your exact question, but as an alternative option, you might consider the following.
Write a recursive method to delete the first occurrence of a specified value, something like this:
public Link deleteFirst(int target) {
if (value == target) {
return next;
}
next = (next == null) ? null : next.deleteFirst(target);
return this;
}
Then you could write a reverse() method as either an iterative or recursive method as you see fit. I haven't included this, but googling should show some useful ideas.
Finally the method to remove the last occurrence of a value from the linked list could then be written like this:
public Link deleteLast(int target) {
return reverse().deleteFirst(target).reverse();
}
Note that as long as your reverse() method is linear complexity, this operation will be linear complexity as well, although constants will be higher than necessary.
The trick is to do the work on the way back -- there is no need for additional parameters, helpers or assumptions at all:
Link deleteLast(int target) {
if (next == null) {
return null;
}
Link deleted = next.deleteLast(target);
if (deleted == null) {
return value == target ? this : null;
}
if (deleted == next) {
next = deleted.next;
}
return deleted;
}

could this remove method for Linkedlist work?

I asked my friends about this and they said you can never take the current to the previous node and when I asked why they didn't give me a clear reason can anyone help me?
//here is the signature of the method;
public void remove (){
Node<T> tmp = null;
tmp.next = head;
// I want to delete the current by the way!;
while (tmp.next != current)
tmp = tmp.next;
tmp.next = current.next;
//now am taking the current to the node before it so that it only becomes null if the linkedlist is empty;
current=tmp;
}
The basic idea is sound if you are looking to mutate an existing linked list and remove an element. Although there is a lack of curly braces after the while and a NullPointException that will occur at the first tmp.next.
Generally a remove method would be passed the data in the node to remove. It's unclear in your question what current is supposed to point to. Your code does not support removing the head of the list or empty lists (null head).
Here's a potential implementation:
public boolean remove(T value) {
if (head == null) {
return false;
} else if (head.value.equals(value)) {
head = head.next;
return true;
} else {
Node<T> current = head;
while (current.next != null) {
if (current.next.value.equals(value)) {
current.next = current.next.next;
return true;
}
current = current.next;
}
return false;
}
}
If the current variable is supposed to end up pointing to the node before the removed node then you have a problem: what happens if you are removing the head of the list?

Circular Linked List Node Insertion Java

I tried implementing the insert method for circular linked list. I think I had some success.
Problem:
When I display the list. The display method will loop because every next variable of the link is linked to a non-null node object. So head will never be a null object. From what I recall about singly linked list, head always point to the first node in the list or the first node with data inside of it.
My conceptual understanding of circular linked list:
From what I can understand circular linked is somewhat like a singly linked list but with a slight twist: the next variable of the tail object points to the head.
I'm coding it like the diagram has presented provided by the source link.
Source: http://sourcecodemania.com/circular-linked-lists/
public void insert(String data)
{
Link link = new Link(data);
if(head == null)
{
head = link;
tail= link;
}
else
{
tail.next = link;
tail = link;
tail.next = head;
}
}
public void display()
{
// good implementation for display #2
while(head != null)
{
// System.out.println (head.data);
head = head.next;
}
}
Once you insert at least one element, you would never come across null. It will keep on going till infinity.
Also, it might not be a good idea to modify head just for displaying the list. Operation like display should not have any side effects.
In stead, keep a member field size in your list class and update it in each insert and delete method.
Now you would know how many times you should iterate the loop.
ListClassName current = head; // Head is not modified.
for (int i = 0; i < this.size; i++) {
// System.out.println (current.data);
current = current.next;
}
Good luck.
You can keep a reference to the first Link object and check to make sure head is not equal to this object while looping:
public void display()
{
boolean first=true;
Link firstItem=null;
// good implementation for display #2
while(head != null && head!= firstItem)
{
if(first){
firstItem=head;
first=false;
}
// System.out.println (head.data);
head = head.next;
}
}

Linked lists method not working properly (java)

I've written a class which represents a polynom using a linked list (members in that list are objects of another class I made called PolyNodes).
In that class I've written this method:
public Polynom addNode (PolyNode p)
{
if (p==null) //if the polynode to be added is null, the same polynom is returned
return this;
if (_head==null) //If the head is null, the polynom is empty and the polynode becomes the polynom
{
_head=p;
return this;
}
PolyNode curr = _head, prev = null;
while(curr != null) //when curr becomes null that means we reached the end of the polynom hence we reached the end of the loop as well
{
if (p.getPower() > curr.getPower()) //Upon reaching the first term whose power is lower than p's power
{
p.setNext(curr);
if (prev == null) //When curr is the polynom's head
_head = p;
else
prev.setNext(p);
return this;
}
else if (p.getPower() == curr.getPower()) //If the polynom already has a term with the same power, p's and curr's coefficients are summed up
{
curr.setCoefficient(curr.getCoefficient() + p.getCoefficient());
return this;
}
prev = curr;
curr = curr.getNext();
}
//If the method reached outside of the loop then there is no term in the polynom whose power is smaller than p's, and p will become the last term in the polynom
p.setNext(null);
prev.setNext(p);
return this;
}
The problem started when I tried writing an addPol() method.
public Polynom addPol (Polynom other)
{
for (PolyNode temp=other._head ; temp!=null ; temp=temp.getNext())
{
addNode(temp);
}
return this;
}
I can't figure out why, but I'm getting wrong results. I went through the code dozens of times and still couldn't find anything that could cause the problem.
problem goes as follows:
when I print list1 I get:
-5.0x^20+5.0x^17+4.0x^11+6.0x^8-5.0x^7+16.0x+1.0
when I print list2 I get
-3.0x^100+2.0x^17-3.0x^4+4.0x
however, when I print list1.addPol(list2)
-3.0x^100-10.0x^20+10.0x^17+8.0x^11+12.0x^8-10.0x^7+32.0x+2.0
If anyone could please tell me what is causing this I would greatly appriciate it. thanks in advance.
When you add the node to a new list its properties get changed, so then when you move onto next you move to the next in the second list.
You would be better off just using the provided LinkedList class for this rather than trying to re-invent it yourself.
Something like:
PolyNode copy = new PolyNode();
copy.setCoefficienttemp.getCoefficient());
copy.setPower(temp.getPower());
addNode(copy);
As mentioned, otherwise temp.getNext() will be changed in the original list.
It would be more abstract to have a class Term + next == PolyNode without next.

LinkedList remove conditions (last iterated item)

I am attempting to remove the last iterated element, with a custom iterator/linked list class. It for some reason only does this for the first item in the list (the head condition). Is there anything wrong with the conditions?
Should I, instead of the Else after If (prev=head), write If (next != null) to find middle nodes, and If (next = null) to find the last node?
Second question: to remove the items, should I also write prev.element = null (now I only have prev = null, and I suppose that erases the node but not its content.
Quite simply, what is wrong with my remove method, as I cannot figure it out myself. Thank you guys so much in advance. I have been working many hours with this but I still haven't got it working.
public E next() {
if (!hasNext())
throw new NoSuchElementException ();
prev = next;
E element = next.element;
next = next.next;
return element;
}
public void remove() {
if(prev == null) {
throw new IllegalStateException();
}
else {
if(prev == head){
head = head.next;
next = head;
}
else {
next = prev.next;
}
sizeOfList--;
prev = null;
}
}
You would need a while loop to be able to go through every node in the list until you hit the last one. As it is now, your code simply goes past the head, and then gets into the code that says sizeOfList-- and then prev = null;
You need something like this:
while (prev.next.next != null) {
prev = prev.next;
}
prev.next = null;
I do prev.next.next so that you can set the 2nd to last node in your linked list to point to a null value (which is done by prev.next = null;). Think of it this way: prev is the 2nd to last element in the list, prev.next is the last element, and obviously prev.next.next HAS to be null (because prev.next is LAST.) So once this is the case, delete the last element by setting the 2nd to last element to point to a null value.
And then decrement your list count.
This is my best guess with the given code
if(prev == head){ should change to if(prev.equals(head)){ Use equals method.
And I think you have to override equals method in the corresponding element class might definitely help.
== only checks for whether both variables refer to same object in memory, where as equals check Object state.
I hope it helps :).

Categories

Resources