栈和队列的互相实现

1 栈和队列

栈: 后进先出的数据结构
队列:先进先出的数据结构
如图所示:

在这里插入图片描述

那么以C++为例,自己使用的编程语言里栈和队列是什么样的呢。可以思考以下几个方面:

  1. C++中的 stack 是容器吗?
  2. 我们使用的stack是属于哪个版本的 STL ?
  3. 我们使用STL中的 stack 是怎么实现的呢?
  4. stack 提供迭代器来遍历 stack 空间吗?

C++标准库是有多个版本的,要知道我们使用的 STL 是哪个版本的,才能知道对应的栈和队列的实现原理,我们> 使用的是SGI STL,是由Silicon Graphics Computer Systems公司参照HP STL实现,被Linux的C++编译器GCC所采用,SGI STL是开源软件,源码可读性很高。
来说一说栈
在这里插入图片描述

  1. 栈提供push 和 pop 等等接口,所有元素必须符合先进后出规则,所以栈不提供遍历功能,也不提供迭代器(iterator)。不像是set 或者map 提供迭代器iterator来遍历所有元素。
  2. 栈是以底层容器完成所有的工作,对外提供统一的接口,底层容器是可插拔的-------我们可以控制使用哪种容器来实现栈的功能。所以STL中栈不被归类为容器,而是容器适配器(配接器)container adapter.

那么STL中的栈是用什么容器实现的呢?

从下图中可以看出,栈的内部结构,栈的底层实现可以是vector,deque,list 都是可以的, 主要就是数组和链表的底层实现
在这里插入图片描述
我们常用的SGI STL,如果没有指定底层实现的话,默认是以deque为缺省情况下栈的低层结构。deque是一个双向队列,只要封住一段,只开通另一端就可以实现栈的逻辑了。

栈说明白后,队列就比较好理解了?

队列 先进先出的数据结构,同样不允许有遍历行为,不提供迭代器, SGI STL中队列一样是以deque为缺省情况下的底部结构。
所以STL中队列也不被归类为容器,而被归类为container adapter( 容器适配器)。

3 用栈实现队列

在这里插入图片描述
https://leetcode-cn.com/problems/implement-queue-using-stacks/

3.1 思路分析

使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈一个输入栈,一个输出栈,这里要注意输入栈和输出栈的关系。
下面引用大佬的动图,https://mp.weixin.qq.com/s/P6tupDwRFi6Ay-L7DT4NVg

3.2 代码实现

class MyQueue {
    
    
    //用两个栈实现队列
public:
    stack<int> stackIn;
    stack<int> stackOut;
    /** Initialize your data structure here. */
    MyQueue() {
    
    

    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
    
    
        stackIn.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
    
    
       //当stackOut中是空的时候把stackIn中的数据导入到stackOut中
       if (stackOut.empty()) {
    
    
           //把stackIn中的数据导入,直到其为空为止
           while (!stackIn.empty()) {
    
    
               stackOut.push(stackIn.top());
               stackIn.pop();
           }
       }
       int result = stackOut.top();
       stackOut.pop();
       return result;
    }
    
    /** Get the front element. */
    int peek() {
    
    
        int ret = this->pop();
        stackOut.push(ret);
        return ret;
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
    
    
       return stackIn.empty() && stackOut.empty();
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */

4 用队列实现栈

在这里插入图片描述
https://leetcode-cn.com/problems/implement-stack-using-queues/

4.1 思路分析

上面做了用栈实现队列,一个输入栈,一个输出栈,那么用队列实现栈也可以这样吗,其实是不行的,队列遵循先入先出的规则,把把一个队列中的数据导入另一个队列中,数据的顺序并没有变,并有变成先进后出的顺序。
所以用队列实现栈的思路可以是:两个队列一个队列是用作备份的作用的。用两个队列que1和que2实现队列的功能,que2其实完全就是一个备份的作用,把que1最后面的元素以外的元素都备份到que2,然后弹出最后面的元素,再把其他元素从que2导回que1。
引用大佬的动图:https://mp.weixin.qq.com/s/yzn6ktUlL-vRG3-m5a8_Yw

4.2 代码实现

class MyStack {
    
    
public:
    //用两个队列实现栈的功能----后进先出
    queue<int> que1;
    queue<int> que2;//用于临时备份数据
    /** Initialize your data structure here. */
    MyStack() {
    
    

    }
    
    /** Push element x onto stack. */
    void push(int x) {
    
    
        que1.push(x);
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
    
    
        //将que1中的数据放入到que2中,直到que1中只剩1个数据
        while (que1.size() > 1) {
    
    
            que2.push(que1.front());
            que1.pop();
        }
        //此时que1中有一个数据
        int ret = que1.front();
        que1.pop();
        //把que2中的数据放回que1中
        while(!que2.empty()) {
    
    
            que1.push(que2.front());
            que2.pop();
        }
        return ret;
    }
    
    /** Get the top element. */
    int top() {
    
    
        return que1.back();//back:队列尾   front:队列头
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
    
    
        return que1.empty();
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

猜你喜欢

转载自blog.csdn.net/CZHLNN/article/details/113849343