在互联网上搜索时,我找到了许多如何使用2个堆栈实现队列的答案?
但是,如何仅使用堆栈的推送和弹出操作来实现队列。堆栈的 push 操作可以与队列的 enqueue 操作类似的方式使用,因为两者都在末尾追加数据。但问题在于实现 deque 操作,因为队列以FIFO方式工作,而堆叠则采用LIFO方式。
我知道某个地方我们将不得不使用递归,因为只使用堆栈的推送和弹出操作来反转堆栈。
我正在编写的伪代码用于使用 push(),pop()&来反转堆栈。堆栈的isEmptyStack()函数是
void reverseStack(Stack s){
if(isEmptyStack(s))
return
temp=pop(s)
reverseStack(s)
push(s,temp)
}
答案 0 :(得分:-1)
可以在没有递归的情况下完成。
1)让我们保持两个堆栈s1和s2(两者最初都是空的)。
2)入队:推送到堆栈s1。
3)deque:如果s2为空,而s1不为空则从s1中弹出元素并将它们推送到s2。 返回pop(s2)。
此解决方案具有O(n)时间复杂度(对于n个查询),因为每个元素仅被推送两次(到s1和s2)并且仅弹出两次。
答案 1 :(得分:-1)
我们不必使用递归。 实际上,使用两个堆栈实现队列并不难。
但是在这里我们只能使用堆栈的标准操作 - 这意味着只能向后推,从前面查看/弹出,大小,并且空操作是有效的。
需要两个堆栈:我们可以单独命名它们的输入和输出 输入用于将每个元素推送到模拟队列(您的目标) 当您想要从模拟队列中弹出元素,或者获取队列的前面时。您应检查输出堆栈是否为空,如果输出为空,则应将所有元素从输入堆栈弹出到输出中。 然后输入中的前一个元素现在位于输出堆栈的顶部。
C ++代码如下:s1 meams输入堆栈,s2表示输出堆栈
class Queue {
public:
// Push element x to the back of queue.
void push(int x) {
s1.push(x);
}
// Removes the element from in front of queue.
void pop(void) {
assert(!s1.empty()||!s2.empty());
if(!s2.empty()) s2.pop();
else {
while(!s1.empty()){
int t=s1.top();
s1.pop();
s2.push(t);
}
s2.pop();
}
}
// Get the front element.
int peek(void) {
assert(!s1.empty()||!s2.empty());
if(!s2.empty()) {
return s2.top();
}
else {
while(!s1.empty()){
int t=s1.top();
s1.pop();
s2.push(t);
}
return s2.top();
}
}
// Return whether the queue is empty.
bool empty(void) {
return s1.empty()&&s2.empty();
}
private:
stack<int> s1;
stack<int> s2;
};`
此外,根据您的语言,您可以使用list或deque来模拟堆栈。