Is Stack with PushAt/PopAt still a Stack? - data-structures

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.

Related

Mutable data types that use stack allocation

Based on my earlier question, I understand the benefit of using stack allocation. Suppose I have an array of arrays. For example, A is a list of matrices and each element A[i] is a 1x3 matrix. The length of A and the dimension of A[i] are known at run time (given by the user). Each A[i] is a matrix of Float64 and this is also known at run time. However, through out the program, I will be modifying the values of A[i] element by element. What data structure can also allow me to use stack allocation? I tried StaticArrays but it doesn't allow me to modify a static array.
StaticArrays defines MArray (MVector, MMatrix) types that are fixed-size and mutable. If you use these there's a higher chance of the compiler determining that they can be stack-allocated, but it's not guaranteed. Moreover, since the pattern you're using is that you're passing the mutable state vector into a function which presumably modifies it, it's not going to be valid or helpful to stack allocate that anyway. If you're going to allocate state once and modify it throughout the program, it doesn't really matter if it is heap or stack allocated—stack allocation is only a big win for objects that are allocated, used locally and then don't escape the local scope, so they can be “freed” simply by popping the stack.
From the code snippet you showed in the linked question, the state vector is allocated in the outer function, test_for_loop, which shouldn't be a big deal since it's done once at the beginning of execution. Using a variably sized state vector to index into an array with a splat (...) might be an issue, however, and that's done in test_function. Using something with fixed size like MVector might be better for that. It might, however, be better still, to use a state tuple and return a new rather than mutated state tuple at the end. The compiler is very good at turning that kind of thing into very efficient code because of immutability.
Note that by convention test_function should be called test_function! since it modifies its M argument and even more so if it modifies the state vector.
I would also note that this isn't a great question/answer pair since it's not standalone at all and really just a continuation of your other question. StackOverflow isn't very good for this kind of iterative question/discussion interaction, I'm afraid.

Implement and merge two stack in O(1)

I've been asked this question somewhere.
I've been given 2 stacks. I have to implement the following operations:
// Pass one of the stacks and a value to insert
push(Stack stack, value)
pop(Stack stack, val)
merge(Stack s1, Stack s2)
I have to perform above stack operations like push and pop in O(1). So far I've used a linked list to successfully implement these operations.
But how can I merge the two stacks in O(1)? I couldn't find how to do it in O(1).
Maybe I need to use some other data structure or something?
It's really easy if your stack objects keep both ends of the stack (top/botton, start/end, head/tail, whatever). I'll use top/bottom for this answer.
When you implement push/pop you operate on the top object. The bottom will remain the same (unless the stack is empty) and the node that represents it will have it's next pointer set to null.
So to merge two stacks you take the bottom of one, point it to the top of the other and return a "new" stack formed of the other pointers.
Stack merge(Stack s1, Stack s2) {
// join the stacks
s2.bottom.next = s1.top
// make a nice object to give back
Stack result;
result.bottom = s1.bottom
result.top = s2.top
// cleanup the parameters so they don't mess up the new structure.
s1.bottom = s1.top = s2.bottom = s2.top = null;
return result;
}
If you don't have the two pointers nicely kept in the stack object you would need to traverse one of the stacks get what would be kept here as bottom, making the complexity O(N).
I would like to give another perspective, the programming/object oriented perspective. If you do not have a pointed to the end of the stack as suggested before and in case merging means first return the elements of one stack, then the other, i.e. define an order between them - this is a real important consideration you did not address. You could follow the following approach
Create a StackList object which extends Stack Java example:
class StackList extends Stack
Now, hold a linked list of Stacks in it, the merging is trivial by adding the Stacks to the list, pop/push will simply call the pop/push methods of the head Stack.

Why do I need stack and queue?

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.

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.

How does the stack work?

I have a couple questions about the stack. One thing I don't understand about the stack is the "pop" and "push" idea. Say I have integers a and b, with a above b on the stack. To access b, as I understand it, a would have to be popped off the stack to access b. So where is "a" stored when it is popped off the stack.
Also if stack memory is more efficient to access than heap memory, why isn't heap memory structured like the stack? Thanks.
So where is "a" stored when it is popped off the stack.
It depends. It goes where the program that's reading the stack decides. It may store the value, ignore it, print it, anything.
Also if stack memory is more efficient to access than heap memory, why
isn't heap memory structured like the stack?
A stack isn't more efficient to access than a heap is, it depends on the usage. The program's flow gets deeper and shallower just like a stack does. Local variables, arguments and return addresses are, in mainstream languages, stored in a stack structure because this kind of structure implements more easily the semantics of what we call a function's stack frame. A function can very efficiently access its own stack frame, but not necessarily its caller functions' stack frames, that is, the whole stack.
On the other hand, the heap would be inefficient if it were implemented that way, because it's expected for the heap to be able to access and possibly delete items anywhere, not just from its top/bottom.
I'm not an expert, but you can sort of think of this like the Tower of Hanoi puzzle. To access a lower disc, you "pop" discs above it and place them elsewhere - in this case, on other stacks, but in the case of programming it could be just a simple variable or pointer or anything. When you've got the item you need, then the other ones can be put back on the stack or moved elsewhere entirely.
Lets take your case scenario .
You have a stack with n elements on it, the last one is a, b is underneath.
pop operation returns the popped value, so if you want to access the second from the top being b, you could do:
var temp = stack.pop()
var b = stack.pop()
stack.push(temp)
However, stack would rarely be used this way. It is a LIFO queue and works best when accessed like a LIFO queue.
It seems you would rather need a collection with a random index based access.
That collection would probably be stored on the heap. Hope it clarified stack pop/push a little.
a is stored wherever you decide to store it. :-) You need to provide a variable in which to store the value at the top of the stack (a) when you remove it, then remove the next item (b) and store it in a different variable to use it, and then push the first value (a) back on the stack.
Picture an actual pile of dirty plates sitting on your counter to your left. You pick one up to wash it (pop it from the "dirty" stack), wash it, dry it, and put it on the top of the clean stack (push it) on your right.
If you want to reach the second plate from the top in either stack, you have to move the top one to get to it. So you pick it up (pop it), put it somewhere temporarily, pick up the next plate (pop it) and put it somewhere, and then put the first one you removed back on the pile (push it back on the stack).
If you can't picture it with plates, use an actual deck of playing cards (or baseball cards, or a stack of paper - anything you can neatly pile ("stack")) and put it on your desk at your left hand. Then perform the steps in my last paragraph, replacing the word "plate" with "card" and physically performing the steps.
So to access b, you declare a variable to store a in, pop a and save it in that variable, pop b into it's own variable, and then push a back onto the stack.

Resources