recursive toString in Queue Linked List in Java - java

I need to implement a toString() recursive method for a linked list Queue. I know my toString method worked fine on a linked list implementation I did last week, so something is wrong with how I'm handling the Queue aspect of it.
toString method for my QueueList:
public String toString()
{
if (front.info == null)
{
System.out.println("Error, queue is empty");
return "";
}
if (front.link == null) //base case: if this is last element in stack
{
return (" \"" + front.info + "\" , ");
}
else //normal recursive function
{
return (" \"" + front.info + "\" , " + front.link.toString());
}
}
and my constructors and such for QueueList:
public class QueueNode
{
E info;
QueueNode link;
}
private QueueNode front;//first element to be placed into queue
private QueueNode rear;//last element to be placed into queue
private int NoE;//counter for number of elements in queue
public QueueList()
{
front = null;
rear = null;
NoE = 0;
}
I tried to see what was going on in it using this test:
public boolean test() {
QueueList<String> q = new QueueList<String>();
q.enqueue("The Godfather");
q.enqueue("Casino");
q.enqueue("Goodfellas");
String r = q.toString();
q.PrettyPrint();
with the output
IN -> [ "The Godfather" , QueueList$QueueNode#a3901c6] -> OUT.
I realize this is because I'm telling saying front.link.toString() in the recursive part of the toString method, but even if I change it to front.link.info.toString(), my output is
IN -> [ "The Godfather" , Casino] -> OUT.
It may be possibly something to do with with my enqueue and dequeue methods then, which are as follows:
public void enqueue(E element)
{
QueueNode newNode = new QueueNode();//creates new Node to hold element
newNode.info = element;//set info of new Node to element
newNode.link = null;//make link null since it's at back of list
if (rear == null)//checks if queue is empty
{
front = newNode;
}
else
{
rear.link = newNode;//sets second to last node's link to newNode
}
rear = newNode;//makes newNode the new last link
NoE++;//increase counter
}
public E dequeue() throws InvalidOperationException
{
if (front == null)//sanitize code
{
throw new InvalidOperationException("There is nothing in the queue.");
}
E element = front.info;//creates an element file that takes the info in front of queue
front = front.link;//makes second-to-front element new front
if (front == null)//if this emptied the queue, make sure rear is also empty
{
rear = null;
}
NoE--;//reduce counter
return element;
}
Please help me out if you can. Thanks.

There is absolutely no need to make toString recursive, and in fact it is incorrect to do so. Your data structure is not recursive (i.e. a tree) but linear.
If your list contained, say, 1 million items, you would quickly run out of stack space (StackOverflow, literally).
Use a loop instead.
EDIT: If you are required do to this recursively, then the issue is that the recursive method must be QueueNode#toStringRecursive(), not Queue#toString(). The method Queue#toString() allocates a buffer and provides it to a special toStringRecursive() method on QueueNode which does the recursion. QueueNode#toString() must be responsible only for its own node contents.
Method Queue#toString()
public String toString()
{
StringBuilder buf = new StringBuilder();
if (front == null)
// queue is empty
else
front.toStringRecursive(buf);
return buf.toString();
}
Method QueueNode#toStringRecursive()
public void toStringRecursive(StringBuilder buf)
{
buf.append(this.toString());
if (this.link != null)
this.toStringRecursive(buf);
}
where QueueNode.toString() is responsible only for stringifying one node (itself).
Note that this is one way to do it. It would be possible to write this as a recursive method on Queue as well, but it could not be called toString(). Queue#toString() would set up the initial conditions and then invoke the recursion.

Related

Display letters in reverse order of stacks

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.

Constructor Node cannot be applied to given types while working with nodes

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.

Java LinkedList adding multiple nodes

my question is in my main method, how to add multiple nodes to the linked list....What I have now with first, node2, node3..I thought was adding those nodes but I realized I don't think I'm actually doing anything with those nodes and their values, right? How do I use setData() and setNext() to add all of those nodes. Does that make sense?
ListNode<String> node4 = new ListNode<String>("Fourth", null);
ListNode<String> node3 = new ListNode<String>("Third", node4);
ListNode<String> node2 = new ListNode<String>("Second", node3);
ListNode<String> first = new ListNode<String>("First", node2);
If the above sets up the values how do I add them all?
Do I then need to set the data and next for each one of these? (This seems redundant since I seem to be setting up the value of each nodes data and next in the constructor above?)
first.setData("first");
first.setNext(node2);
node2.setData("Second");
node2.setNext(node2);
//.....
I'm trying to add all of the above nodes so I can test my addLast() method by adding a new node. However, when I call my addLast() method in main as you can see below the only thing that's printed is that addLast() value I added (and first if I call addFirst()).
Test Class
public class LinkedListDriver
{
public static void main(String[] args) {
//List<String> list = new LinkedList<String>(); //comment out this line to test your code
SinglyLinkedList<String> list = new SinglyLinkedList<String>(); //remove comment to test your code
ListNode<String> node4 = new ListNode<String>("Fourth", null);
ListNode<String> node3 = new ListNode<String>("Third", node4);
ListNode<String> node2 = new ListNode<String>("Second", node3);
ListNode<String> first = new ListNode<String>("First", node2);
ListNode value = new ListNode("First", new ListNode("Second", new ListNode("Third", null)));
//I've been messing around with this but
list.addFirst(first.getData());
list.addFirst("Second");
list.addLast("Fifth");
list.printList();
}
}
I didn't add my other two classes because I didn't think it was relevant but if you'd like to see it let me know. I'm very new this is only my second class and it's online and is poorly constructed class, please be nice lol
SinglyLinkedList class
//This class implements a very simple singly-linked list of Objects
public class SinglyLinkedList<E>
{
ListNode<E> first; // first element
public SinglyLinkedList() {
first = null;
}
public E getFirst() {
if (first == null) {
throw new NoSuchElementException();
} else
return first.getData();
}
public void addFirst(E value) {
first = new ListNode<E>(value, first);
}
// Methods below implemented by you. Note: while writing methods, keep in mind
// that you might be able to call other methods in this class to help you - you
// don't always need to start from scratch(but you'll have to recognize when)
public void addLast(E value) {
ListNode<E> temp = first;
//If list is empty make new node the first node.
if (temp == null) {
first = new ListNode <E>(value, null);
first.setNext(null);
}//Otherwise loop to end of list and add new node.
else {
while (temp.getNext() != null) {
temp = temp.getNext();
}
temp.setNext(new ListNode<E>(value, null));
}
}//end addLast
// throws an exception - you decide when and which one
public E getLast() {
ListNode<E> temp = first;
if (temp == null) {
throw new NullPointerException("There are no elements in this list to get.");
} else {
while (temp.getNext() != null) {
temp = temp.getNext();
}
return temp.getData();
}
}
// throws an exception - you decide when and which one
public E removeFirst() {
if (first == null) {
throw new NullPointerException("There are no elements in this list to remove.");
}
ListNode<E> tempRemove = first;
return null; //just so it'll compile
}
// throws an exception - you decide when and which one
public E removeLast() {
return null; //just so it'll compile
}
// return the number of elements in the list
public int size() {
return 0; //just so it'll compile
}
// return true if o is in this list, otherwise false
public boolean contains(E obj) {
return true; //just so it'll compile
}
public void printList(java.io.PrintStream out) {
if (first == null) {
System.out.println("The list is empty");
}
ListNode<E> current = first;
while (current != null) {
System.out.println(current.toString());
current = current.getNext();
}
}
public String toString() {
String s = "[";
ListNode<E> current = first;
//write code to traverse the list, adding each object on its own line
while (current.getNext() != null) {
current = current.getNext();
}
s += "]";
return s;
}
// OPTIONAL: just for fun...and a challenge
public void reverse() {
}
}
ListNode class is your basic getNext setNext, getData setData....
A couple of points, mostly summarizing the comments:
You shouldn't work with ListNode objects in main() at all - that should be the job of the SinglyLinkedList class. ListNode doesn't even need to be visible to the rest of the code, it could be a nested class in SinglyLinkedList. You should only be exchanging the data objects (Strings in this case) with SinglyLinkedList.
If you want to test for example the addLast() method, you could start with an empty list and repeatedly call list.addLast(), as Shane mentions in his answer. That way you will make sure it works when the list is empty as well as nonempty.
SinglyLinkedList<String> list = new SinglyLinkedList<String>();
list.addLast("first");
list.addLast("second");
list.addLast("third");
list.printList(System.out);
As for adding multiple nodes in a single call - this linked list doesn't have a method for that. You could add a method for adding all elements of an array for example, but you can just call addLast() sequentially with the same effect. You can create some helper method in the main class to populate the list in this way, if you want to start with some base data for testing other methods.
As a side note: if printList() takes java.io.PrintStream out as argument, you should use it instead of System.out. That is
out.println(...)
instead of
System.out.println(...)
Also, it's better to throw NoSuchElementException rather than NullPointerException as an indication that the requested element doesn't exist.
If you want a convenient way to populate the list, you could have something like this in your main class:
static <E> void addToList(SinglyLinkedList<E> list, E... values) {
for (E value : values) {
list.addLast(value);
}
}
and use it like this:
SinglyLinkedList<String> list = new SinglyLinkedList<String>();
addToList(list, "first", "second", "third");
What are you trying to do? If you're attempting to populate the linked list, all you need to do is continually call list.addLast, which will take a single parameter (the data in the new node you're adding), and deal with creating the new node and placing it in the back of the list.
You shouldn't need to create any nodes in your main, I'm assuming, as they are generally handled entirely by the linkedlist class.

Get Exception in thread "main" java.lang.NullPointerException with LinkedList

Simple Linked List
public class List_manager {
Entry first;
Entry last;
public void add(String el) {
if (isEmpty()) { first=new Entry(el); last=first; return; }
new Entry(el,last);
}
public String get() {
Entry temp=first;
first=first.next;
return temp.data;
}
public boolean isEmpty() {
return first==null;
}
private class Entry {
String data;
Entry next;
public Entry(String data,Entry to) {
this.data=data;
to.next=this;
to=this;
}
public Entry(String data) {
this.data=data;
}
}
}
#The main class#
I added 3 element and list contains only 2... why?
public class Main {
public static void main(String[] args) {
List_manager l=new List_manager();
l.add("1");
l.add("2");
l.add("3");
System.out.println(l.get());
System.out.println(l.get()); // Why here output: "3"??
System.out.println(l.get()); // here is an error occurs
}
}
I really don`t get why list contains 2 elements?
Why it ignores 2nd added element?
to=this; This sentence have no influence on variable 'last', because veriable 'to' is formal parameter, while variable 'last' is actual parameter. So, when you executed this sentence "to = this;" the value of
variable 'last' was not changed to next.That's mean variable 'last' always pointed to the first element.
my change is : new Entry(el,last); --> last = new Entry(el,last);
Things look better.
Think about what your get method is doing. You already noticed some aberrant behavior with it.
public String get() {
Entry temp=first;
first=first.next;
return temp.data;
}
What happens the first time I call this?
temp gets whatever first is pointing to
first is moved to its next element (RED FLAG)
temp's data is returned...
One problem is that you're moving your head reference around - this is a bad idea, since it means that you can never access the true first element in your list ever again.
Now on its own, even with this implementation, you should still be able to get the first element.
The above was just a red herring - although you should not be moving your head pointer around. This is the real problem. What happens on subsequent add calls to your list?
public void add(String el) {
if (isEmpty()) {
first = new Entry(el);
last = first;
return;
}
new Entry(el,last);
}
Only the first element inserted and the last element inserted are respected. All other entries after next are overwritten.
I suggest that you use a debugger to figure this one out, as it stems from a misunderstanding of a good approach to do this. You only want to insert things through your tail pointer once you have one element. Doing this through object creation only causes heartache and confusion.
For posterity, I'll leave you with a sample, verbatim implementation I wrote for a singly linked list implementation I did a while back. It describes a more viable approach to inserting into a list.
public void insert(E data) {
Node<E> candidate = new Node<>(data);
if(head == null) {
head = candidate;
tail = head;
} else {
tail.setNext(candidate);
tail = tail.getNext();
}
size = size + 1;
}

Recursion and LinkedList in Java

Ok so say I have a function that looks for a specific word in a custom LinkedList class:
public LinkedList find(String word) {
if (this.word.equals(word))
return this;
if (next==null)
return null;
if (next.find(word)==next)
return next;
return null;
}
This code works fine, however it returns the FIRST found object that matches the criteria. What if I wanted to return the LAST object found that matches the paramater? I'm having a hard time figuring this out. Keep in mind I want to use recursion.
EDIT: What would be wrong with this code:
public LinkedList findLast(String word) {
LinkedList temp=new LinkedList(word, null);
if (next==null && next.word.equals(word))
return next;
if (next==null && !next.word.equals(word))
temp=next.findLast(word);
return temp;
}
Well, think of it this way: you need to recurse right to the end of the list, and then let the return value bubble up.
So the start of your method should either be a recursive call to look further down the list, or noting that we're at the end of the list - which is equivalent to the "further" result being null.
Now when you're returning, there are three options:
You've already found a match later than the current point - so return that reference
You've not found a match (so the return value of the recursive call was null) and:
The current point's word matches - so return the current point
The current point doesn't match - so return null
Hopefully that should be enough to get you to an implementation - if not, please ask more questions. I'd rather not give a full implementation when this is presumably homework.
Store a reference to the latest one found and keep on calling itself until it returns null -- then return the latest-reference.
Note, for clarification: you're going to have to iterate through your entire linked-list (unless you have a doubly-linked-list) to achieve this -- store a reference every time you find a match (but just overwrite the same reference each time) -- then return whatever the reference holds once you reach the end of this list.
public class LinkedList {
private static int uniqueIdCounter = 0;
private final String word;
private int uniqueId;
private LinkedList next = null;
public LinkedList( String word ) {
this.word = word;
this.uniqueId = uniqueIdCounter++;
}
#Override
public String toString() {
return this.word + "(" + this.uniqueId + ")";
}
public void setNext( LinkedList next ) {
this.next = next;
}
public LinkedList find( String word ) {
return this.find( word, null );
}
public LinkedList find( String word, LinkedList result ) {
if( this.word.equals( word ) ) {
result = this;
}
if( this.next != null ) {
result = this.next.find(word, result);
}
return result;
}
public static void main(String[] args) {
LinkedList head = new LinkedList( "A");
System.out.println( "Head is: " + head );
LinkedList B = new LinkedList( "B" );
head.setNext( B );
System.out.println( "B is: " + B );
LinkedList A2 = new LinkedList( "A" );
B.setNext( A2 );
System.out.println( "A2 is: " + A2 );
LinkedList last = head.find( "A" );
System.out.println( "Last is: " + last );
}
}
And here's the output:
Head is: A(0)
B is: B(1)
A2 is: A(2)
Last is: A(2)
Every straight recursive function has two places for some useful actions: before further method call and after:
function(n){
doBefore(n);
function(n+1)
doAfter(n)
}
doBefore() is executed "on the way forward", doAfter() is executed "on the way back". Now your algorithm checks word equality on the way forward. You have to modify your algorithm so that this check is performed on the way back.
public LinkedList find(String word, LinkedList result) {
if (this.word.equals(word))
result = this;
if (next != null )
return next.find(word, result)
return result;
Two-liner:
public LinkedList find(String word, LinkedList result) {
result = this.word.equals(word) ? this : result;
return next == null ? result : next.find(word, result);
#fprime: Ya, explanation: remember the result, replace it with later result, return when at the end.
Method with one argument:
public LinkedList find(String word){
result = this.word.equals(word) ? this : null;
if(next != null)
previous = next.find(word);
return (previous != null) ? previous : result
else
return result;
Just run it backwards from the tail.
public LinkedList find(String word) {
if (this.word.equals(word))
return this;
if (prev==null)
return null;
if (prev.find(word)==prev)
return prev;
return null;
}
To start with, you initial find(String word) does not work correctly.
Your first if statement is perfect. It is you success base case.
Your second if statement is also perfect. It is your failure base case.
Your third is where you go off the rails. You have handled all (in this case both) base cases, now all that is left is the recursive case. You don't need to check anything here. next.find(word) will return the correct answer, success or fail.
For findLast(String word), I can't add much to what Jon Skeet said. About the only advice I can add it to never have the a node check its neighbor. Each node should only ever check itself. You should see plenty of this.word.equals(word) but never next.word.equals(word).
public LinkedList find(String word) {
if(this.word.equals(word)) return this;
return next==null?null:next.find(word);
}
public LinkedList rfind(String word) {
if(next != null) {
LinkedList res = next.rfind(word);
if(res != null) return res;
}
return this.word.equals(word)?this:null;
}

Categories

Resources