For school I had to made a kind of linked list like queue.
My nodes have 3 attributes:
Node left (Node left of the node)
Node right (Node right of the node)
Object item (The object that is stored in the list)
I also have to make the list iterable so implemented that interface.
The problem I have now is that if there are for example 4 items in the list, it only shows 3 of them.
So if for example the list has 4 strings in it, 'a', 'b', 'c' and 'd' the output is:
b
c
d
My hasNext method looks like:
#Override
public boolean hasNext() {
return node.getRight() != null;
}
and my next method looks like:
#Override
public T next() {
node = node.getRight();
Object item = node.getItem();
return (T)item;
}
If I return the item of the node instead of the node on the right I get
a
b
c
as return but that is also not good because it skips the last one. And when you read the API next should return the next value so I guess my next method has to be as it is.
The iterator's methods should be implemented as this:
#Override
public T next() {
Object item = node.getItem();
node = node.getRight();
return (T)item;
}
#Override
public boolean hasNext() {
return node != null;
}
Just think about other iterators. At the first call of next() they return the first element and THEN they move forward to the second. When you are pointing to the last element, next() should return it and move forward (i.e. point to null). To be able to do this, the test inside of hasNext should be on the current item, not on the next, otherwise you could not get the last element.
You probably initialize the node property by setting it to the first node, so a next () call points to the second. Try checking for the first node:
boolean first = true;
#Override public T next() {
if (!first) {
node = node.getRight();
}
else
first = false;
Object item = node.getItem();
return (T)item;
}
Related
I wrote this code of stacks using a linked list but I am having a problem with the code it prints the letters in reverse order without creating a function to display the letters in reverse order
class SimpleLinkedListStack2 implements SimpleStack ,Iterable {
static class ListNode<T> {
public T value;
public ListNode<T> next;
public ListNode(T value, ListNode<T> next) {
this.value = value;
this.next = next;
}
}
private ListNode<T> head = null;
private int count = 0;
public Iterator<T> iterator() {
return new Iterator<T>() {
private ListNode<T> next = head;
#Override
public boolean hasNext() {
return next != null;
}
#Override
public T next() {
if (next == null)
throw new NoSuchElementException();
T value = next.value;
next = next.next;
return value;
}
};
}
#Override
public void push(T value) {
head = new ListNode<>(value, head);
count++;
}
#Override
public T pop() throws Exception {
if (count == 0) {
throw new Exception("Stack is empty");
}
T value = head.value;
head = head.next;
count--;
return value;
}
#Override
public T peek() throws Exception {
if (count == 0) {
throw new Exception("Stack is empty");
}
return head.value;
}
}
this is the main class
public class main {
public static void main(String[] args) {
SimpleLinkedListStack2 <String>stack2= new SimpleLinkedListStack2<>();
stack2.push("a");
stack2.push("b");
stack2.push("c");
stack2.push("d");
stack2.push("e");
for (String letters : stack2){
System.out.println(letters);
}
}
}
the out but is
e
d
c
b
a
because I need to make a function to display the letters in reverse order in the class SimpleLinkedListStack2
Just walk through your code:
stack2.push("a");
This changes your stack's head from null to a node that has no next and whose value is "a". Your stack is now: -> ["a", -> null], where -> is 'pointing at object'.
stack2.push("b");
And now your stack is -> ["b", -> ["a", -> null]]: You create a new ListNode object for "b", and update its 'next' pointer to be what head was, and then head points at this newly created thing.
Thus, of course, if you then iterate through it, you get the last thing you added ("b" here), first.
Hence, your code pritns e d c b a - it's what you put in the list, in reverse order, because that's what you programmed, and that's what stacks are (they are 'Last in, First Out' - the last thing you put it is the e, and that's the first thing that comes out, as per the design!
But I want to print in the same order I put the items in!
This is a so-called 'singly linked list', meaning, any given LinkedNode knows its next node, but does not know its previous node. You cannot in-place reverse-walk-through a singly linked list - what you want is not possible without drastic steps.
For example, you could make an entirely new stack, just by iterating through this stack, which naturally ends up with the newly created stack being the exact reverse of the original. And then print that reversed stack, and then toss it away (java is garbage collected; that part happens automatically). There is no 'easy' solution / no solution that takes no memory. You could also just build the string out, and then reverse that instead.
Perhaps that's the point of this homework exercise, to make you think about how these LinkedNode objects relate to each other in memory. Get out a pad of paper and go sketch it out. Boxes and arrows. You'll figure it out.
I am working on a code that puts new elements on MyStack if they are unique. I had to copy and paste the node starting code, so I'm having a bit of trouble with an issue. I keep getting two error messages, even after trying various workarounds and I'm not really understanding why. I've even tried using some helper functions I've previously made that have worked before so I'm extra confused.
The two errors I consistently get are:
-cannot infer type arguments for MyStack.Node (actual and formal arguments differ in length)
-constructor node cannot be applied to given types. Required, no arguments, found: anything,
Here's my code:
public class MyStack<Anything>
{
private Node first, last;
private class Node<Anything>
{
Anything item;
Node next;
}
public boolean contains(Anything value)
{
for (Node curr = first; curr != null; curr = curr.next)
{
if (value.equals(curr.item)) {
return true;
}
}
return false;
}
public void add(Anything value)
//method that adds a new value to the end of the list
//COMPLETE
{
Node temp = first;
while(temp.next!=null){ //finds the end
temp=temp.next;
}
temp.next=new Node(value, null); //assigns new value
}
public void enqueue(Anything info){
if (this.contains(info)==true) { //if the info is already present
System.out.println("the stack already contains this value");
return;
}
//if we actually need to add the info
if (first == null) { //if there is nothing in the stack
Node temp= first;
first = new Node<>(info,temp);
first = temp;
return;
}
if (first != null) { //if there is already stuff
Node temp = first;
while (temp.next == null)
{ Node newNode= new Node<>(info, temp);
temp.next = newNode;
}
return;
}
}
}
As #Andreas already pointed out, Node needs a constructor.
There are a few other flaws in your Code:
Use Generics
With your Code, you can only store Objects of the class Anything, what strongly limits its reusability. Use a generic instead and you can reuse this class for many more purposes.
Linked List
I suggest, you use the paradigm of a double-linked-list. That way you do not need to find the last Node to add something to the Stack. Node now has a pointer to its previous and next element.
Use the last Object
You have the object last but never use it. To find out, whether the current object is the last one you compare the value to null. This has the effect, that storing a null value will break your List. Instead compare to the Object last, this object is unique and guarantees you, that you are at the end of the list. Both first and last are Nodes that do not contain a value and are simply used to mark the start/end of your List.
Adding elements
Using the changes above, the code in the Method enqueue(T value) becomes significantly simpler: You just check whether contains(value) and decide whether you add the value to the List or not.
All these changes applied result in following code:
public class MyStack<T extends Object> {
private Node first, last;
public MyStack() {
first = new Node(null, null, null);
last = new Node(null, null, first);
first.next = last;
}
private class Node {
T item;
Node next;
Node previous;
public Node(T item, Node next, Node previous) {
this.item = item;
this.next = next;
this.previous = previous;
}
}
public boolean contains(T value) {
for (Node curr = first.next; curr != last; curr = curr.next) {
if (value.equals(curr.item)) {
return true;
}
}
return false;
}
/**
* method that adds a new value to the end of the list
*/
public void add(T value)
{
Node secondLast = last.previous;
Node added = new Node(value, last, secondLast);
secondLast.next = added;
last.previous = added;
}
/**
* only adds value if it is not already contained by the Stack
*/
public void enqueue(T value) {
if (this.contains(value) == true) { // if the info is already present
System.out.println("the stack already contains this value");
}
else {
add(value);
}
}
public static void main(String[] args) {
MyStack<String> test = new MyStack<>();
test.add("foo");
test.add("bar");
test.add("baz");
System.out.println(test.contains("bar"));
System.out.println(test.contains("new"));
test.enqueue("baz");
test.enqueue("MyStack");
}
}
Naming
As you may have noticed, in my explanation I called this class a List. This is because it fulfills more of the characteristics of a List. A Stack usually only provides the methods push to put something at the top of the Stack and pop to remove and return the topmost Object. Optionally peek can return the topmost Object, without removing it from the Stack.
Also consider renaming the method enqueue: enqueue is used in Queues (obviously) and Queues do not forbid to add two equal Objects. So the name is misleading. I would call this method something like addIfNotContaining.
In my Opinion you should name this class to be a List and add a method get(int i) to get a specific element at a position. Naturally adding some other methods like size ect. to comply with a standard List. But I assume you already had, but did not post them because they are not related to your problem.
Multithreading
This Class is far from threadsave. But I let you figure out yourself how to make it threadsave if needed.
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;
}
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.
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 :).