i know how to implement stack using one or two queues, but how about n stacks using only 4 queues?
is it possible at all? if it is would you please explain the algorithm?thank you.
Yes it is.
Assuming you can implement a stack from 2 queues (as your question states), the "4 queues" is now just noise, and if you can implement n stacks using 2 stacks, the answer to your question is yes.
This can be done by pushing to the stack not only the element, but the stack's id as well. When popping, you push elements to the other stack, until you find element from required stack, and then return them back.
This can probably be optimized to avoid pushing all the way back over and over again, but I believe worst case complexity is still linear in the number of elements.
Here is a (very unoptimized) pseudo code.
Pop(stack_number):
element = null
while not head_stack.empty():
if head_stack.peek()[0] == stack_number:
element = head_stack.pop()
break
else:
other_stack.push(head_stack.pop())
while not other_stack.empty():
head_stack.push(other_stack.pop())
return element
Push(stack_number, element):
head_stack.push({stack_number, element})
Related
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.
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.
Assuming the tree is balanced, how much stack space will the routine use for a tree of 1,000,000 elements?
void printTree(const Node *node) {
char buffer[1000];
if(node) {
printTree(node->left);
getNodeAsString(node, buffer);
puts(buffer);
printTree(node->right);
}
}
This was one of the algo questions in "The Pragmatic Programmer" where the answer was 21 buffers needed (lg(1m) ~= 20 and with the additional 1 at very top)
But I am thinking that it requires more than 1 buffer at levels lower than top level, due to the 2 calls to itself for left and right node. Is there something I missed?
*Sorry, but this is really not a homework. Don't see this on the booksite's errata.
First the left node call is made, then that call returns (and so its stack is available for re-use), then there's a bit of work, then the right node call is made.
So it's true that there are two buffers at the next level down, but those two buffers are required consecutively, not concurrently. So you only need to count one buffer in the high-water-mark stack usage. What matters is how deep the function recurses, not how many times in total the function is called.
This assuming of course that the code is written in a language similar to C, and that the C implementation uses a stack for automatic variables (I've yet to see one that doesn't), blah blah.
The first call will recurse all the way to the leaf node, then return. Then the second call will start -- but by the time the second call takes place, all activation records from the first call will have been cleared off the stack. IOW, there will only be data from one of those on the stack at any given time.
I'm studying now for the final exam and I see the following question at the end of the professor's ppt slides, which are talking about the Stack:
What is a Double Stack?
I know that the stack is an ordered collection of homogeneous elements (i.e. a list), in which all insertions and deletions are made at one end of the list called the top of the stackm but what is the double stack? I tried search through google and I had no luck with finding an answer.
It could be 2 stacks which are stored in a single array and grow in opposite direction.
http://www.ceglug.org/index.php/labs/45-double-stack-implementationwith-structuresand
Though this is the only reference i found.
A DoubleStack is a stack of double values.
You can find more info at
http://www.cis.syr.edu/courses/cis351/docs/edu.colorado.collections.DoubleStack.html.gz
Double stack means two stacks which are implemented using a single array. To prevent memory wastage, the two stacks are grown in opposite direction. The pointer tops1 and tops2 points to top-most element of stack 1 and stack 2 respectively. Initially, tops1 is initialized as -1 and tops2 is initialized the capacity. As the elements are pushed into stack 1, tops1 is incremented. Similarly, as the elements are pushed into stack 2, tops2 is decremented. So, the array is full when tops1=tops2-1. Beyond this, pushing an element into any stack will lead to overflow condition.
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.