使用push& amp;实现队列堆栈的弹出操作

时间:2014-06-23 01:46:02

标签: algorithm stack queue

在互联网上搜索时,我找到了许多如何使用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)
}

2 个答案:

答案 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来模拟堆栈。