自学内容网 自学内容网

代码随想录--栈与队列--用栈实现队列

队列是先进先出,栈是先进后出。

如图所示:
在这里插入图片描述

题目

使用栈实现队列的下列操作:

push(x) – 将一个元素放入队列的尾部。
pop() – 从队列首部移除元素。
peek() – 返回队列首部的元素。
empty() – 返回队列是否为空。

示例:

MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek(); // 返回 1
queue.pop(); // 返回 1
queue.empty(); // 返回 false

说明:

你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。

思路

这是一道模拟题,不涉及到具体算法,考察的就是对栈和队列的掌握程度。

使用栈来模拟队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈一个输入栈,一个输出栈,这里要注意输入栈和输出栈的关系。

下面动画模拟以下队列的执行过程:

执行语句:
queue.push(1);
queue.push(2);
queue.pop(); 注意此时的输出栈的操作
queue.push(3);
queue.push(4);
queue.pop();
queue.pop();注意此时的输出栈的操作
queue.pop();
queue.empty();
在这里插入图片描述在push数据的时候,只要数据放进输入栈就好,但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入),再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。

最后如何判断队列为空呢?如果进栈和出栈都为空的话,说明模拟的队列为空了。

在代码实现的时候,会发现pop() 和 peek()两个函数功能类似,代码实现上也是类似的,可以思考一下如何把代码抽象一下。

C++代码如下:
class MyQueue {
public:
stack stIn;
stack stOut;
/** Initialize your data structure here. */
MyQueue() {

}
/** Push element x to the back of queue. */
void push(int x) {
    stIn.push(x);
}

/** Removes the element from in front of queue and returns that element. */
int pop() {
    // 只有当stOut为空的时候,再从stIn里导入数据(导入stIn全部数据)
    if (stOut.empty()) {
        // 从stIn导入数据直到stIn为空
        while(!stIn.empty()) {
            stOut.push(stIn.top());
            stIn.pop();
        }
    }
    int result = stOut.top();
    stOut.pop();
    return result;
}

/** Get the front element. */
int peek() {
    int res = this->pop(); // 直接使用已有的pop函数
    stOut.push(res); // 因为pop函数弹出了元素res,所以再添加回去
    return res;
}

/** Returns whether the queue is empty. */
bool empty() {
    return stIn.empty() && stOut.empty();
}

};

时间复杂度: push和empty为O(1), pop和peek为O(n)
空间复杂度: O(n)

Java

class MyQueue {

Stack<Integer> stackIn;
Stack<Integer> stackOut;

/** Initialize your data structure here. */
public MyQueue() {
    stackIn = new Stack<>(); // 负责进栈
    stackOut = new Stack<>(); // 负责出栈
}

/** Push element x to the back of queue. */
public void push(int x) {
    stackIn.push(x);
}

/** Removes the element from in front of queue and returns that element. */
public int pop() {    
    dumpstackIn();
    return stackOut.pop();
}

/** Get the front element. */
public int peek() {
    dumpstackIn();
    return stackOut.peek();
}

/** Returns whether the queue is empty. */
public boolean empty() {
    return stackIn.isEmpty() && stackOut.isEmpty();
}

// 如果stackOut为空,那么将stackIn中的元素全部放到stackOut中
private void dumpstackIn(){
    if (!stackOut.isEmpty()) return; 
    while (!stackIn.isEmpty()){
            stackOut.push(stackIn.pop());
    }
}

}


原文地址:https://blog.csdn.net/weixin_52297290/article/details/142746168

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!