【问题标题】:Implement queue using push & pop operation of stack使用栈的push和pop操作实现队列
【发布时间】:2014-08-12 23:49:17
【问题描述】:

在互联网上搜索时,我找到了很多关于如何使用 2 个堆栈实现队列?
的答案 但是如何仅使用堆栈的推送和弹出操作来实现队列。 stack 的 push 操作可以以与队列的 enqueue 操作类似的方式使用,因为两者都在末尾追加数据。但问题在于实现 deque 操作,因为队列以 FIFO 方式工作,而堆栈以 LIFO 方式工作。
我知道在某个地方我们将不得不使用递归,以防仅使用堆栈的推送和弹出操作来反转堆栈。 我正在编写的使用堆栈的 push(),pop() 和 isEmptyStack() 函数来反转堆栈的伪代码是

void reverseStack(Stack s){
if(isEmptyStack(s))
return

temp=pop(s)
reverseStack(s)
push(s,temp)
}

【问题讨论】:

标签: algorithm stack queue


【解决方案1】:

不用递归也可以做到。

1)让我们维护两个栈 s1 和 s2(最初都是空的)。

2)入队:推入栈 s1。

3)deque:如果 s2 为空,而 s1 不为空,则从 s1 弹出元素并将它们推送到 s2。 返回 pop(s2)。

此解决方案的时间复杂度为 O(n)(对于 n 个查询),因为每个元素仅被推送两次(到 s1 和 s2)并且仅弹出两次。

【讨论】:

    【解决方案2】:

    我们不必使用递归。 其实用两个栈来实现队列并不难。

    但是这里我们只能使用堆栈的标准操作——这意味着只有推到后面、从前面窥视/弹出、大小和空操作是有效的。

    需要两个堆栈:我们可以将它们分别命名为输入和输出。
    输入用于将每个元素推入模拟队列(您的目标)。
    当您想从模拟队列中弹出元素,或获取队列的最前面时。您应该检查输出堆栈是否为空,如果输出为空,则应将输入堆栈中的所有元素弹出到输出中。 那么输入中的前一个第一个元素现在位于输出堆栈的顶部。

    C++代码如下:s1表示输入栈,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;
    };`
    

    此外,根据您的语言,您可以使用列表或双端队列模拟堆栈。

    【讨论】:

      猜你喜欢
      • 2016-01-08
      • 2021-12-06
      • 2021-09-06
      • 1970-01-01
      • 2016-08-16
      • 2011-05-04
      • 2020-06-29
      • 2013-04-20
      • 2020-08-24
      相关资源
      最近更新 更多