Deque ("doubled-ended queue") operations, en-queue and de-queue are possible from both ends.
How do to I define ADT operations for deque using 2 stacks?
The implementation should also take performance into consideration.
Deque ("doubled-ended queue") operations, en-queue and de-queue are possible from both ends.
How do to I define ADT operations for deque using 2 stacks?
The implementation should also take performance into consideration.
the simplest solution would be to use one stack as the head of the queue, and one as the tail. The enqueue operations would just be a push to the respective stack, and the dequeue operations would just be a pop on the respective stack.
However, if the stack you want to dequeue from is empty, you'd have to pop each element from the other stack and push it back to the stack you want to dequeue from, and then dequeue the last one. That's not really good performance, so the overall performance of this implementation strongly depends on the workload. If your workload is a balanced number of front/back enqueue and dequeue operations, then this will be really really fast. But if your workload consists of a lot of alternating head-dequeues and tail-dequeues while the queue is large, then this will obviously be a bad approach.
Hope this helps
This is how I did it, what really matters is that you make sure when you keep poping from one and it gets empty then it starts to pop from the other one, ( we got to make sure it pop from the end of stack ) we can do this by emptying one stack into the another. and keep poping there.
public class NewDeque {
Stack<E> frontstack;
Stack<E> endstack;
public NewDeque() {
frontstack = new Stack<>();
endstack = new Stack<>();
}
void addFirst(E e) {
frontstack.push(e);
}
E delFirst() {
if (frontstack.isEmpty()) {
while (!endstack.isEmpty()) {
frontstack.push(endstack.pop());
}
return frontstack.pop();
}
return frontstack.pop();
}
void addLast(E e) {
endstack.push(e);
}
E delLast() {
if (endstack.isEmpty()) {
while (!frontstack.isEmpty()) {
endstack.push(frontstack.pop());
}
return endstack.pop();
}
return endstack.pop();
}
int size() {
return frontstack.size() + endstack.size();
}
boolean isEmpty() {
return (size() == 0) ? true : false;
}
E get(int i) {
if (i < endstack.size()) {
return endstack.get(endstack.size() - i - 1);
} else {
return frontstack.get(i - endstack.size());
}
}
static void print(NewDeque<Integer> ds) {
for (int i = 0; i < ds.size(); i++) {
System.out.print(" " + ds.get(i) + " ");
}
}
an interesting way to do this is as follows
enqueue(q, x)
1) Push element x to stack1. This very simple, the problem is dequeue
dequeue(q)
1) If stacks1 and stack2 are empty then error "UNDERFLOW"
2) If stack2 is empty, then
while (stack1 is not empty) do
push all element from satck1 to stack2.
end while;
3) Pop the element from stack2 and return it.
Found this solution for ArrayStacks. I think, something like that could work for any kind of stacks. You can use Andreas Grapentin answer, but add to it a balance function, that should be called sufficiently rarely. The idea is that when the balance between two stacks is too shifted, you should push them into an array (ordered as the queue), then split this array at the middle and copy its halves back to stacks.
© 2022 - 2024 — McMap. All rights reserved.