Why do I need stack and queue? - data-structures

Well,this question has been asked before and I read about the implementations of stack and queue.But I feel like those things can also be implemented with array or list.For example: LIFO(Last in First Out) can easily be implemented in python by using list.
Then why do we need stack and queue?

Stack and Queue are data-structures. Each of them has certain properties. For example Stack is LIFO(last in first out) whereas Queue is FIFO(first in first out).
In case of implementation - it is totally upto you how you are implementing those. For example if you are using C++, then you can use array or vector or even linked-list to implement those. Similar case is for python. You can tweak list to your expected behavior(like stack or queue). In a more simplified definition - Stacks are basically array or list which has the property of LIFO and Queues are basically array or list which has the property of FIFO.
Now why do you need Stack or Queue? - well suppose if you need a data-structure which has the property of LIFO( or FIFO). What do you do? you can tweak list as per your need. But if in your program needs multiple stacks(or queues), what do you do then? Well you can implement a stack(which underneath uses list), which will give you a generic template, which you can re-use multiple times.

Related

What is the technical error if we declare a Deque as a general one which allows input and output from both sides?

We know that a Deque has two sub category...
Input restricted and output restricted...
Now what is the technical error in designing a Deque in such a way that it has no restrictions
i.e. The user can enter and remove data from both the front and back at any time ...with any restrictions !!!
Under Distinctions and sub-types, the Wikipedia article says, "This general data class has some possible sub-types:" It then goes on to list the input- and output-restricted. Note that they are possible sub-types. Nothing in the article or any other literature I've seen says that you can't have an unrestricted deque, and in fact many runtime libraries provide such.
So there is a deque (unrestricted double-ended queue), and there are input-restricted and output-restricted deques.
It's perhaps a bit of a stretch, but one could make the argument that both FIFO queues and LIFO stacks are also deque sub-types. The FIFO queue is input-restricted at one end and output-restricted at the other. A LIFO stack is input- and output-restricted at the same end.

Can someone explain how std::greater is used to implement priority_queue

std::priority_queue<int, vector<int>, std::greater<int> > pq;
I cannot understand the work of std::greater in the priority queue.
I am replacing minheap by the priority queue.
this code is taken from
geeksForGeeks implementation of Prims algorithm using STL
The std::priority_queue type is what’s called a container adapter. It works by starting with a type you can use to represent a sequence, then uses that type to build the priority queue (specifically, as a binary heap). By default, it uses a vector.
In order to do this, the priority queue type has to know how to compare elements against one another in a way that determines which elements are “smaller” than other elements. By default, it uses the less-than operator.
If you make a standard std::priority_queue<int>, you get back a priority queue that
uses a std::vector for storage, and
uses the less-than operator to compare elements.
In many cases, this is what you want. If you insert elements into a priority queue created this way, you’ll read them back out from greatest to least.
In some cases, though, this isn’t the behavior you want. In Prim’s algorithm and Dijkstra’s algorithm, for example, you want the values to come back in ascending order rather than descending order. To do this, you need to, in effect, reverse the order of comparisons by using the greater-than operator instead of the less-than operator.
To do this, you need to tell the priority queue to use a different comparison method. Unfortunately, the priority queue type is designed so that if you want to do that, you also need to specify which underlying container you want to use. I think this is a mistake in the design - it would be really nice to just be able to specify the comparator rather than the comparator and the container - but c’est la vie. The syntax for this is
std::priority_queue<int, // store integers...
std::vector<int>, // ... in a vector ...
std::greater<int>> // ... comparing using >

Constant-time list concatenation in OCaml

Is it possible to implement constant-time list concatenation in OCaml?
I imagine an approach where we deal directly with memory and concatenate lists by pointing the end of the first list to the beginning of the second list. Essentially, we're creating some type of linked-list like object.
With the normal list type, no, you can't. The algorithm you gave is exactly the one implemented ... but you still have to actually find the end of the first list...
There are various methods to implement constant time concatenation (see Okazaki for fancy details). I will just give you names of ocaml libraries that implement it: BatSeq, BatLazyList (both in batteries), sequence, gen, Core.Sequence.
Pretty sure there is a diff-list implementation somewhere too.
Lists are already (singly) linked lists. But list nodes are immutable. So you change any node's pointer to point to anything different. In order to concatenate two lists you must therefore copy all the nodes in the first list.

There is nothing innately slow about GolfScript. (...) Analysis could be done to remove most if not all stack use. Explain?

From http://www.golfscript.com/golfscript/syntax.html ,
Ruby is slow to start with so GolfScript is even slower. There is
nothing innately slow about GolfScript. Except for the string evaluate
method, everything could be statically compiled into C, and analysis
could be done to remove most if not all stack use. I do not plan on
making a more efficient interpreter, as the purpose of language is not
numerical analysis, however if any feels like creating one, I would be
delighted to use it.
Could someone illustrate with simple examples what are stacks, what does it mean to eliminate all stack use and how that could be done?
GolfScript is a stack-based language. Its behavior is similar to an RPN calculator. Each builtin consumes some number of the topmost stack values and pushes its results back onto the stack for future operations. If you want to test if a number is less than a constant, you'd use code like .5< where the . duplicates the value (because otherwise it would be consumed and lost) and then the constant is pushed. Finally < pops the copy and the constant and pushes back the result. A compiler could easily see a pattern like .X< and generate code which skips the intermediate steps (just "peek" at the top of the stack and compare). This would be in the category of "peephole" optmizations, which look for small output patterns and replace them with more efficient patterns.
Sometimes it would not be possible, if the values on the top of the stack came from complex (unpredictable) calculations.

Is Stack with PushAt/PopAt still a Stack?

Lets say I have a Data Structure similar to Stack but in addition to usual Push/Pop it also has functions such as PushAt/PopAt both of which takes an integer as input and adds/returns the item at that particular location in data structure.
Now Stack is suppose to be LIFO. Does this data structure qualify as "Stack"?
In HP RPN calculators and in Postscript/PDF, other operators than push and pop exist:
swap or exch for permuting top of stack and next element,
roll as an extension of swap
Their main data structure is still considered a stack.
pushAt and popAt can be written only with pop/push and roll. So your data structure can still be named stack.
Technically not. LIFO means (as you know) last-in, first-out. If the last element going in isn't the first to come out, it doesn't satisfy the "semantic interface" (or contract) of a stack.
However, since it seems like you are only adding additional methods and not modify the existing ones your data structure could be used interchangeably with a stack if it is being used like one, i.e. pushAt() and popAt() are never called (for instance because they are "hidden" by passing it as a Stack to a function).
So in that sense your version is a stack in the same way that a list is a stack in Java, for example. It can be used as one, but it can also do other things.
It's not a stack because it's not LIFO, you have complete control of where the items are get/set it's just a normal list imho.
Implementation of this would be easy if a linked list were to be used due to how the pointers can be reassigned, although if you were to use an array it would be difficult to pop an entity in the middle and then resize the structure to fill the gap below a complexity of O(n^2). This complexity would be very inefficient with linked list the complexity would only be O(n).
It might look like an ADT, but it just sounds like an array.
IMO it's a stack as long as it supports Push and Pop. It doesn't matter if it also supports other actions.
If its not a LIFO object it can't be qualified as a Stack. I would say its simply a List with Push Pop functionality which again is nothing but AddAtEnd() and RemoveFromEnd()
Your data structure can be used as a stack.. or as an array/list..
Stack is just a specialized form of a list.. and your implementation appears to negate that specialness.. so I would lean towards calling it a list instead of a stack.
Actually if you can only Pop and Push elements you can still see it as Stack. A more flexible stack.

Resources