How would I go about writing an implementation of push for the stack ADT using list ADT? Assuming i'm pushing to the top of stack, would I have to create a temp list and do something to add the previous head to the tail?
private someList<E> stack;
public void push(E element){
stack.add(element);
}
//another file
public someList<E> add(E newHead){
return new someList<E>(newHead, this);
}
What is important in the implementation of the stack ADT, is where you are going to add the new elements you push and where you are going to delete elements you pop. Obviously push(someElement); pop(); should leave the stack unchanged.
So we have 2 choices, adding/removing elements at the end of the list or in the front.
public void push(E element){
stack.add(element);
}
You've chosen to add/remove them at the end of the list.
I don't know what the add method has to do, however if it returns a new someList which represents a/the new stack, then the private stack field should get this newly created stack assigned!
Note that if the purpose of add is to change the current head (replace current TOS (= Top Of Stack) by this one), then you could simply write it as follow
public someList<E> add(E newHead){
pop(); // remove TOS
push(newHead); // Add newHead as the new TOS
return this.stack;
}
I've implemented the stack ADT for String's. I leave it as a simple exercise to change it to your needs (using someList instead of List and using generics).
public class Stack {
private List<String> stack = new ArrayList<String>();
public void push(String element){
stack.add(element);
}
public List<String> add(String newHead){
stack = new ArrayList<String>(stack); // you should do "stack = new someList<E>(newHead, this);"
return stack; // return the new stack
}
public String pop() {
String res = stack.get(stack.size() - 1);
stack.remove(stack.size() - 1); //
return res;
}
public void printStack() {
System.out.println("TOS (Top Of Stack)");
for(int i = stack.size() - 1; i >= 0; i--)
System.out.println(stack.get(i));
System.out.println("EOS (End Of Stack)");
}
}
// Test it
...
String a = "a", b = "b";
Stack stck = new Stack();
stck.push(a);
stck.push(b);
stck.push(b);
stck.push(a);
stck.pop();
stck.printStack();
...
This is how the stack is changing during the test case.
TOS (Top Of Stack)
a ---> b ---> b ---> a ---> b
a b b b
a b a
a
EOS (End Of Stack)
Note that in this implementation of the stack ADT we are pushing/popping elements from the stack by adding/removing elements from the list's tail (more precisely arrayList). Which is ideal for use with java's arrayList because adding an element to the tail of the list, or removing the last element, is in O(1).
Methods specifying insertion position have to copy all array elements to the right from insertion
(Source)
You will have to check if the same holds when using your own someList implementation. However, if adding an element to the tail of the list (or removing the last element) requires you to traverse the whole list (which is the case for e.g. a single linked list, hence O(n)), then adding/removing the first element should be in O(1).
In that case you should change the stack ADT's implementation so that the front of someList is now representing the TOS and the tail of the list is representing the end of the stack. Hence push/pop will then add/remove elements at the front of the list.
EDIT : You could implement a count method :
By explicitly remembering how many elements are on the stack (i.e. you have a size field that you increment for every push() and decrement for every successful pop() (i.e. for every pop() when size > 0 then decrement size).
By relying on the size() method of the ArrayList that is used to represent the stack.
Hence a possible implementation
public class Stack {
private List<String> stack = new ArrayList<String>();
...
public int count() {
return stack.size();
}
}
Related
I am currently using Java to complete a test module which is concerned about implementing a stack using Linked List.
I have implemented the push() operation but for the pop() operation I did not get the correct result.
I Tried as following :
public class LLStack implements LLStackQInterface{
SintNode head = new SintNode(0);
#Override
public void push(int num) {
head.nextNode = new SintNode(num);
head = head.nextNode;
}
#Override
public int pop() {
SintNode t = head;
while(t.nextNode!=null)
{
t=t.nextNode;
}
t = null;
return 0;
}
I have to push out the latest element so I navigate to last element in the list using t pointer but I did not get the result!
I do get this as the result :
Failed for the input: PUSH 1 PUSH 3 POP PUSH 4 PUSH 6
POP PUSH 8 PUSH 9 POP
Expected output is: 8->4->1->NULL
Actual output generated by your code: 9->8->6->4->3->1->NULL
I managed to reverse the list but clearly my pop() does not work. What shall I do?
Both your pop and push methods are bugged.
Your management of next pointers in push is incorrect. You first set the next pointer of the current head to the new node, and then assign the new node to head. Therefore, head.next == null. The correct way to do it is:
public void push(int num) {
SintNode n = new SintNode(num);
n.next = head;
head = n;
}
This way, you insert the new node at the front of the list and maintain a pointer to the next element, i.e. the previous head of the list.
In your pop method, you traverse to the end of the list. This is incorrect, since you add elements to the front of the list. A stack is a LIFO (Last-In First-Out) data structure, meaning you should remove the last element that was inserted. In this case, it is the head of the list.
public int pop() {
if (head == null)
return 0;
SintNode t = head;
head = t.next;
t = null;
return 0;
}
Here, we first set the new head to be head.next, and then delete the current head.
I ran the corrected version, and the actual output matches the expected output.
#Override public void push(int num) {
// store a copy of the current head
SintNode temp = this.head;
// update the current head to the pushed value
this.head = new SintNode(num);
// link the head to the rest of the stack, as each subsequent node will point to another one until the tail
this.head.nextNode = temp; }
#Override public int pop() {
// assuming SintNode has a value property
int value = this.head.value;
// remove this node by overwriting it as the next
this.head = this.head.nextNode;
// the value of removed node
return value; }
I'm trying to move list elements to the stack and back to the list again, reversing their order.
I'm having trouble with the last bit of transferring the stack back into the list.
I've been using the stack.pop(); in different ways but nothing seems to work.
I'm able to just print out the output of stack.pop so far, but I really want to be able to transfer the stack contents back into the list.
public class ReverseArray {
public static void main(String[] args) throws EmptyStackException {
// TODO Auto-generated method stub
MyLinkedList<GameEntry>myList = new MyLinkedList<>();
//populate the list
myList.addFirst(new Node<GameEntry>(new GameEntry("Marche", 313), null));
myList.addFirst(new Node<GameEntry>(new GameEntry("Apricot", 754), null));
myList.addFirst(new Node<GameEntry>(new GameEntry("Dragon", 284), null));
myList.addFirst(new Node<GameEntry>(new GameEntry("Erasure", 653), null));
//print the list
System.out.println(myList);
System.out.println();
System.out.println("New Reversed List:");
//reverse the list elements
reverse(myList);
}
public static <V> void reverse ( MyLinkedList<V> list) throws EmptyStackException{
//code to reverse goes here
NodeStack<GameEntry> stack = new NodeStack<GameEntry>();
Node<GameEntry> scores = list.getHead();
for ( int i = 0; i < list.getSize(); i++){
stack.push(scores.getElement());
scores = scores.getNext();
}
while(!stack.isEmpty()){
System.out.print(stack.pop() + " ");
}
}// end reverse
}//end main
You should keep order from the stack, so add them at the end of a new LinkedList:
while(!stack.isEmpty()){
GameEntry entry = stack.pop();
list.addLast(entry);
}
Assuming you want the list to only contain the reversed elements you have to clear the list at first. Depending on your implementation you have a clear() method or must call remove() several times until the list is empy.
Afterwards you can add code like this:
while(!stack.isEmpty()){
GameEntry entry = stack.pop();
list.addFirst(entry);
}
That way you should have the reversed order of your elements in the list.
An alternativ would be implementing the List Interface with your MyLinkedList and use the Collections.reverse().
Totally missed that the order would be the same as on the input list. Therefore you have two options:
Use a Queue instead of a Stack.
Use second Stack that gets filled with the contents of your first Stack. This may look like:
NodeStack<GameEntry> secondStack = new NodeStack<GameEntry>();
while(!stack.isEmpty()){
secondStack.push(stack.pop());
}
while(!secondStack.isEmpty()){
GameEntry entry = secondStack.pop();
list.addFirst(entry);
}
This is not a HW or assignment. This is something i'm practicing myself.
Given a queue, write a Reverse method reverses elements of a queue. MyQueue remains unchanged.
Signature:
public Queue<T> reverse(Queue<T> myQueue) {
Note: It is unknown if the Queue is made using nodes or array.
The queue has methods already implemented, that we can use:
void enqueue(T element)
T dequeue();
boolean isFull();
boolean isEmpty();
int size();
You can reverse a queue by using a stack.
Here's how in Java:
public void reverse(Queue q)
{
Stack s = new Stack(); //create a stack
//while the queue is not empty
while(!q.isEmpty())
{ //add the elements of the queue onto a stack
s.push(q.serve());
}
//while the stack is not empty
while(!s.isEmpty())
{ //add the elements in the stack back to the queue
q.append(s.pop());
}
}
The append and serve methods of the queue are to add and remove elements of that queue.
Here's an example:
A queue has elements:
1 2 3 4
When the elements get added to a stack, the number 1 will be at the bottom of the list and 4 at the top:
1 2 3 4 <- top
Now pop the stack and put the elements back in the queue:
4 3 2 1
I hope this helped.
dequeue the elements of the input queue onto a stack
pop the elements off the stack, enqueueing each into the output queue.
You can do this without any other arrays or lists, just by recursion:
public static <T> Queue<T> flip(Queue<T> q) {
Queue<T> ret = new Queue<>();
recursiveFlip(q, ret);
return ret;
}
private static <T> void recursiveFlip(Queue<T> src, Queue<T> dest) {
T buffer = src.dequeue();
if(!src.isEmpty()) {
recursiveFlip(src, dest);
}
dest.enqueue(buffer);
}
First elements will be stacked in "shallow" part of the stack, while last elements in "deeper" part, and when recursion reaches the end, the "deeper" values will be added first and "shallow" last.
But note that each one element means one step deeper into recursion, so stack overflow error will occur if the queue is too big.
Also, the original queue will not "survive" the flip.
I've used two different approaches that don't depend on your queue size. The first one uses Stack and second one - Java 8 Stream API (the fastest).
The most effective solution for reversing queue in my tests is:
private Queue<Integer> reverse(Queue<Integer> queue) {
List<Integer> collect = queue.stream()
.collect(Collectors.toList());
Collections.reverse(collect);
return new LinkedList<>(collect);
}
My understanding of why arraylist is faster than a linkedlist is that with an arraylist you basically only need one action - update the reference at the end array element, whereas with a linked list you have to do much more e.g. create a new node, update 2 references, go through linked list and update the last node to point to the new one etc.
However I am not sure how java implement these. How does the arraylist know where the "last" element is, does it store a value of the last element or does it traverse the array and add a new element after the last?
And linked lists, do they store a reference to the last node in the list, or do they traverse the entire list to get to the end?
Look at the source:
ArrayList:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
LinkedList:
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
An array-list is only faster at certain operations. If you add an element in the middle of an array the arraylist needs to copy basically all data into a new array. It is only if the arraylist already have allocated room for new data it is fast when inserting data where it is empty (usually in the end). Read/update by index is very-fast.
A LinkedList is fast when inserting since it never require the whole array to be copied. But accessing data in a linked list is slow since you need to "walk" all the elements until you are at the element you want to find.
You can always look at the sources of java.* classes.
However, answering particular your question: there is int field in ArrayList class, which contains current size of filled internal array area. When you add new value in ArrayList object, this field increments and then directly addresses to that element in internal array.
I'm using a custom LinkedList class that goes like this:
public class LinkedList {
// Get and Set methods are NOT necessary!
private LinkedList next;
private final String word;
public LinkedList(String word, LinkedList next) {
this.word = word;
this.next = next;
}
Now my task is to write a method that takes an array of Strings, and coverts each string object into a LinkedList WITHOUT loops, so using recursion. How can this be done without loops? This is unimaginable to me. Where do I begin?
Edit: Let me clarify that the function I'm supposed to write only takes one argument, which is an array of Strings, and returns a LinkedList..
enter code here
public LinkedList arrayToLinkedList(String[] myArray)
{
String[] toConvert = myArray;
List<String> toConvertList = (List) Arrays.asList(toConvert);
LinkedList<String> convertedLinkedList = new LinkedList<String>(toConvertList);
return convertedLinkedList;
}
Probably just me, but I don't like any of the solutions provided.
/**
* Creates linked list from array input.
*
* #param input
* data array
* #return linked list with data
*/
public static LinkedList Of(String[] input) {
// Checks if array has elements.
if (input == null || input.length < 1)
return null;
// Starts creating the array using overload 2.
return LinkedList.Of(input, 0);
}
/**
* Creates linked list from array input (overload 2).
*
* #param input
* data array
* #param i
* counter to remember at what element is current
* #return linked list with data
*/
public static LinkedList Of(String[] input, int i) {
//Tests if counter is within array elements.
if (input.length - 1 > i)
// Returns new element with (current element data, reference
// to next element). Note that next element will be returned
// by this same method (this is why it is recursive).
return new LinkedList(input[i], LinkedList.Of(input, i + 1));
//Last element. From here backtracking will begin.
return new LinkedList(input[i], null);
}
Here is something else:
public String toString() {
StringBuilder sb = new StringBuilder(this.word);
LinkedList tmp = this;
while (tmp.next != null) {
sb.append(" > ");
tmp = tmp.next;
if (tmp.word != null)
sb.append(tmp.word);
}
return sb.toString();
}
And to test:
String str = "Neque porro quisquam est qui dolorem ipsum quia "
+ "dolor sit amet, consectetur, adipisci velit...";
LinkedList ll = LinkedList.Of(str.split("\\s+"));
System.out.println(ll);
I'm not sure what language you are using, but here's a general idea:
public LinkedList myfunction(String arr[]) {
if(arr.empty == true)
return void;
//return the array minus the first element
String shorterarray[] = substr(arr[],1);
//recursively create the next element
LinkedList myItem = new LinkedList(arr[0], myfunction(shorterarray[]));
}
You'll have to do the subtring and boundary checking in whatever language you are using.
How about:
public static void main(String[] args) {
String[] data = new String[] { "1", "2", "3" };
LinkedList head = build(data);
while (head != null) {
System.out.println(head.word);
head = head.next;
}
}
private static LinkedList build(String[] data) {
if (data == null || data.length == 0) {
return null;
}
LinkedList head = new LinkedList(data[0], null);
build(head, data, 1);
return head;
}
private static LinkedList build(LinkedList node, String[] data, int index) {
if (index == data.length) {
return node;
}
node.next = build(new LinkedList(data[index], null), data, ++index);
return node;
}
private static class LinkedList {
private final String word;
private LinkedList next;
public LinkedList(String word, LinkedList next) {
this.word = word;
this.next = next;
}
}
To add, it might also be worth while pointing out that creating collections with recursion is really bad in practice - it can easily blow out your stack size.
First, anything you can do with iteration (looping) you can do with recursion, and vice-versa (though without tail-call elimination, something Java doesn't have, recursion is often more expensive than iteration).
When trying to figure out how to solve a problem recursively you want to figure out how to break off one or more pieces of the problem that look like the same sort of problem but only smaller. With list problems that often means that when given an n element list you want to recursively handle n-1 elements. You also need to have a base case so the recursion will terminate. With lists the base case is usually a list of 0 elements.
An array is a lot like a list, but Java arrays don't have slicing (ie: you can't pass around just a piece of an array) so you'll want a helper method that knows which piece of the array we care about:
private static LinkedList fromArray(String[] a, int offset) {
Since your LinkedList class breaks down into a word and then the tail part of the list (pointed to by next) it makes sense for us to also deal with the tail part of the input array. The offset parameter lets us know how much of the tail part of the array we'll be looking at: it's the first index we care about.
The public method will just call the helper method giving it an offset of 0:
public static LinkedList fromArray(String[] a) {
return fromArray(a, 0);
}
An offset of 0 means we care about element 0 (the first element) and every element after it.
So now to write the "helper" method, which is where all of the real work is done.
First, get the base case out of the way. The base case is where the part of the array we're converting is empty. That would be the case if offset >= a.length. In that case we want to return an empty LinkedList, which is actually represented by null. So return null in that case.
Once the base case is taken care of, think about the recursive case. We have one or more elements in the part of the array we care about. Let's create a LinkedList to hold the first of those elements, a[offset]. (The first element we care about, that is. Recall that the helper only cares about the part of the array starting at offset up to the end.) The rest of the elements can be handled by calling ourselves passing in the same array, but incrementing offset by one, as we don't want the recursive call to handle the element we already handled.
Call a function that takes three arguments; a source array, a current position in the array, and a destination linked list.
Does that get your head going/can you figure it out from there?
Try this:
private LinkedList formlist(LinkedList list, String[] str, int length, int i) {
if(i==length)
return list;
return formlist(new LinkedList (str[i],list),str,length,i+1);
}
Ok, since there is the requirement for a single method with String[] args.
here is a java example. (based on a previous answer but converted to java)
private LinkedList build(String arr[]) {
if(arr.length == 0)
return null;
//return the array minus the first element
String shorterarray[] = Arrays.copyOfRange(arr, 1, arr.length);
//recursively create the next element
return new LinkedList(arr[0], build(shorterarray));
}