I know it is possible for implement a stack using linked list. Is it possible to implement a linked list using stack ?
If it possible,then how ? I did not get any references from anywhere.
If it's a singly linked list, implement push by adding at the head, and pop by removing from the head. You don't want to use the tail because you would need to keep iterating from the head to the tail to find the new top when you do a pop.
There's an example here: Stack
If it's a doubly linked list, pick an end and implement push and pop by adding and removing at that end. Either end will be as efficient as the other because you have pointers going both ways so you can easily find the new top after a pop.
To answer your second question, I don't think you can implement a linked list using a stack. A stack is a strictly simpler ADT than a list.
You can simulate a linked list by using two stacks. One stack is the "list," and the other is used for temporary storage.
To add an item at the head, simply push the item onto the stack. To remove from the head, pop from the stack.
To insert into the middle somewhere, pop items from the "list" stack and push them onto the temporary stack until you get to your insertion point. Push the new item onto the "list" stack, then pop from the temporary stack and push back onto the "list" stack. Deletion of an arbitrary node is similar.
This isn't terribly efficient, by the way, but it would in fact work.
Related
I'm new to data structures and it seems like both data structures have more similarities.
In this answer it says that there is a difference in interface.
Please explain it.
A queue is any data structure that is "FIFO = First-In First-Out." It's a waiting-list. (In Britain, the term is used in ordinary conversation ... you "wait in a queue" not "wait in line.")
A stack is any data structure that is "LIFO = Last-In First-Out." It's a pushdown stack like the stack of dishes in a cafeteria.
Linked lists are a possible implementation of either such structure. It consists of nodes which contain pointers to adjacent nodes in the list.
However, there are many other implementations. "Trees" of various kinds can also be used to implement both queues and stacks. Ordinary arrays can do it, although of course arrays cannot "grow."
Ideally, these days, you simply use an appropriate "container class" in your favorite language and fuhgeddabout how it actually was implemented. "You know that it works, therefore you don't care how." Actual implementation of such things is probably an academic exercise.
List is just a list of things (items, objects whatever). For example a list of courses you are taking in your semester. A list of songs that you are listening. A list of answers of this question on this page. There is no order associate with a list. You can add an item to a list anywhere, you can take an item off the list from anywhere, it doesn't change the definition of a list. Its just a grouping of similar (or not so similar) items.
Now consider a list of people standing in front of ATM machine or a bank teller. This list has to observe a particular order. The first person in the line (list) is the one that will be served first (and will be the first to leave this list). A new person coming in will be standing as a last person in the queue and will be served after everyone in front of him has been served. The people in middle of the list are not supposed to jump the line. This is an example of a Queue. You can also guess what a priority Queue would be (think Airlines with silver and gold members on check-ins).
I hope this explains the difference.
A link list is a list of nodes. Each node contain an address field and that address field holding the address of its next node. The reason for this kind of structure is to traverse through the list from its first node till last node. This type of structure is called singly link list. A link list can also be doubly linked, in that structure a node will have two address field where one field will store the address of its previous node and one address will hold the address of its next node. Most important thing of a link list is that its first node address must be stored in an address variable so that we can traverse through the link list at any time.
But Queue can be a link list or an array of nodes. In a list a node can be insert at any place. But in queue a new node must be inserted at the beginning of the list. A queue is working on basis of FIFO i.e. first in first out basis. Hence when you use the pop command on a queue if it is a link list it must remove the last node of the list and return the value of that last node. Hence a queue can be a list as well but with a principle called FIFO based.
You will get more information online. Read properly and try to understand the difference.
I had the same question as you! This is what I found:
A Queue is essentially just more restrictive than a LinkedList. For example, in a LinkedList you can use the method .add(int index, Object obj), but if you try doing that with a Queue interface, you’ll get an error, since with a Queue you can only add elements at the tail end. Similarly, in a LinkedList you can use .remove(int index) as well as .remove(Object obj), but attempting to do this with a Queue will result in an error, since you can only remove an object from the head. So, in essence, the Queue just has less options when it comes to methods you can use on it. (There might be more to it than that, but that’s what was most pertinent to me.)
There are some similarities between the two. For example, they both have the .poll() method, and the result is the same: removes the head element from the Object.
Here are some links in which you can compare the methods of the two (scroll to the bottom of each page to see them all, and you’ll see immediately that LinkedList has a lot more):
https://www.geeksforgeeks.org/linked-list-in-java/ (LinkedList)
https://www.geeksforgeeks.org/queue-interface-java/ (Queue)
In Java (and probably other languages too), a LinkedList implements the Queue interface. So in essence, a LinkedList is a Queue; it has all features that a Queue does and more. Keep in mind, a Queue is not a LinkedList, as a LinkedList is built and expanded upon a Queue.
See this:
Does the sequence to insert an element really matters in stacks or queues,i mean to push or to enqueue the data either at start or at the end given we are popping from top in a stack and dequeue from the head in a queue.........Forgive me if this has been already asked.
I hope the question is clear.Thanks in advance.
Check this picture
A stack is a basic data structure that can be logically thought as linear structure represented by a real physical stack or pile, a structure where insertion and deletion of items takes place at one end called top of the stack. The basic concept can be illustrated by thinking of your data set as a stack of plates or books where you can only take the top item off the stack in order to remove things from it. So yeah this is a data structures not a open source project, sequence matters.
Same goes for Queue
I need a collection that is efficient when pre-appending and returning the first element. A stack does the job well.
Now, the objects of the stacks is also a collection. Let's say it is a list. So I have a Stack of Lists.
My question is the following:
If I want to append an element to the list of the head of the Stack, is my only choice to: pop the head, add the element to the list and push the new list?
Efficiently wise, all times are constant, correct?
If you're working with immutable collections the list you'd add and the outer stack(or List) would be new as well so it doesn't matter. Still lists are efficient in prepend and head operations (you can check doc for Collection - performance characteristics for details on the costs of operations)
Implementing a queue or a priority queue using two stacks are not hard.
Now the questions are
How about using only ONE stack to implement a priority queue?
How about using only ONE stack to implement a normal queue?
Are they even possible?
p.s. of course you should use constant extra space other than ONE stack if necessary
No, it's not possible using only methods provided through a stack interface (i.e. using only push and pop methods) with constant extra space. [1]
Consider trying to simulate a queue using a stack.
When enqueueing, if we simply push onto the stack, we'll end up with another element we need to do something with to get to the front of the queue for a dequeue. It's easy to see that a bunch of enqueues will make it impossible for the next dequeue to take a constant amount of space, as all these enqueued elements need to be popped to get to the front of the queue. We could also put the enqueued element a constant number of elements from the top of the stack, but this doesn't really help much either - the elements below it will need to be dequeued first, so we run into the same problem. Trying to put the enqueued element further than a constant number of elements from the top of the stack will of course take more than a constant amount of space already.
Now consider a priority queue where each new item has lower priority than all items already in the queue. This is synonymous to a simply queue, which, from the above argument, can't be simulated using a single stack with constant space.
[1]: If the stack was implemented as an array or linked-list, as it typically is, it would of course be possible using the functionality for those, but I'm sure that's not what you're asking.
Say you push n elements onto your stack. Now you want the element at the bottom of it (if you want to implement a queue). You're going to need extra O(n) space to keep your other n-1 elements so you can access the bottom one.
=> Under your constraints and only the stack interface methods, there's no way you're going to implement a queue using a single stack and constant space.
It is impossible to perform the task if you only allow standard stack operations (pop, push), as queueing an item would mean poping all the items from the stack, pushing the new item, and then push back all the items. If you use constant time, you can't pop all the items and keep track of them with O(1) memory.
Let's assume you implement a stack with a two-way linked list and allow a reverse method- meaning you flip the order of the stack (tail of the linked list becomes the tail).
Now, for a regular queue, you can perform:
queue- perform reverse, push the new item, and reverse again.
dequeue- perform pop.
Note once you allow a reverse action, it's not a standard stack anymore.
A priority queue is still impossible impossible to implement even if you allow reverse, as you'll still have to perform various comparisons when queueing or dequeueing, and will still encounter the problem of having no space to store the items you want to compare.
Here's a solution that is technically correct, but almost certainly useless for your purposes.
We use a stack S of queues (regular or priority). We initialise S to hold a single empty queue. For any queue operation, we peek at the top element of S and apply the queue operation to it in place. This way, S will only ever hold a single element.
This uses zero memory outside of the stack, if you take the viewpoint that the stack "owns" the memory of all its elements.
I was just going through past slides of one of the courses being offered in my University.
Here is the slide which mentions this question: http://www.cse.psu.edu/~asmith/courses/cse565/F10/www/lec-notes/CSE565-F10-Lec-03.pptx.pdf
However, I am not sure if I correctly understand the question and am also thus clueless on the solution.
Any pointers on what the problem is and how to think about it?
To simulate an array you need to allow for indexed lookup.
Insert:
Given 2 unbounded stacks, call them foo and bar, initially you can keep inserting to foo.
Lookup:
When the user tries to lookup an element, you simply pop the stack.size - index times into the bar. The next pop will give you the element user is looking for. However at this point you can do a peek instead of a pop because the array does not delete its elements on lookup.
Now you can either push all the elements back onto foo from bar or push the rest of the elements from bar onto foo. But in the latter case, you need to reverse you indexing.
Delete:
To implement a delete you can simply mark the element as deleted. If the user ever tries to inserting an element at that index you can pop and push the new element. Whereas on lookup you should return whatever represents an empty index.
The primary tasks:
appending
removal
insertion
indexed lookup
Lets call the two stacks "S1" and "S2"
Appending
to append something, pop everything from S2, pushing them onto S1, then push the new value onto S1
Pop
Pop everything from S2, pushing them onto S1, then pop the last item on S1
Indexed removal
Pop everything from S2 onto S1. Pop the first i items from S1 into S2. Pop the top off of S1.
insertion
To insert at index i (0 based), pop everything off of S1 into S2, then pop the first i items off of S2 and push them back onto S1. Now push your value onto S1.
indexed lookup
Pop everything off of S2 and push them onto S1. Now pop the first i items off of S1 and push them into S2. The item you are looking for should be the top item on S1.
Note
the Pop-everything and push onto another process can be dramatically simplified by keeping track of how many items there are total, and where you are currently. If you keep track of these two (or any other numbers that reflect these), then you can calculate exactly how many you need to transfer instead of counting from the beginning.
This implementation isn't as much an "array" implementation as much as a "list" implementation. It's essentially a simplified linked-list (the next node is just under the current node, the previous node is on the top of the other stack) where the only data you have is the current node.
Keep a bogo-index and current value in memory, values at lower indices in one stack and values at higher indices in another. To go to another index, keep popping from the appropriate stack and pushing the current value to the other, and decrement/increment the bogo-index until it's where you want. You can wrap it up with bounds checks if you like.