代码随想录第十天 栈与队列

文章讨论了C++标准模板库(STL)中栈和队列的实现,指出栈作为容器适配器而非容器,通常使用vector、deque或list作为底层实现。栈不提供迭代器,遵循先进后出原则。队列默认以deque为底层结构,同样不提供迭代器,遵循先进先出原则。此外,文章还展示了如何使用两个栈实现队列的操作,以及如何用队列模拟栈的行为。
摘要由CSDN通过智能技术生成

栈与队列的示意图如下:

所以,栈是先进后出,队列是先进先出 

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

 (1)栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能)。

    所以STL中栈往往不被归类为容器,而被归类为container adapter(容器适配器)。

(2)栈提供push 和 pop 等等接口,所有元素必须符合先进后出规则,所以栈不提供走访功能,也不提供迭代器(iterator)。 不像是set 或者map 提供迭代器iterator来遍历所有元素。

那么问题来了,STL 中栈是用什么容器实现的?

从下图中可以看出,栈的内部结构,栈的底层实现可以是vector,deque,list 都是可以的, 主要就是数组和链表的底层实现。

我们也可以指定vector为栈的底层实现,初始化语句如下:

std::stack<int, std::vector<int> > third;  // 使用vector为底层容器的栈

队列中先进先出的数据结构,同样不允许有遍历行为,不提供迭代器, SGI STL中队列一样是以deque为缺省情况下的底部结构。

也可以指定list 为起底层实现,初始化queue的语句如下:

std::queue<int, std::list<int>> third; // 定义以list为底层容器的队列

232.用实现队列:

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

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

可以借助两个栈实现队列的效果。

代码如下:

class  MyQueue {
public:
    stack<int, vector<int>>stIn;  //使用容器定义一个进栈
    stack<int, vector<int>>stOut;//使用容器定义一个出栈
    queue<int, vector<int>>que;
    //获取队列对头元素
    void push(int x) {
        stIn.push(x);//push函数代表从栈头出第一个元素
    }
    //实现弹出队头元素
    int pop() {
        if (stOut.empty()) {
            while (!stIn.empty()) {
                stOut.push(stIn.pop());//stOut栈添加从stIn栈弹出的元素
                stIn.push();  //继续向stIn添加元素
            }
        }
        int result = stOut.top();
        stOut.pop();//弹出stOut栈头元素,实际上这个就相当于队列的头元素
        return result;
    }

    //获取队列头部元素
    int peek() {
        int res = this->pop();
        stOut.push(res);
        return res;
    }
    //是否为空
    bool empty() {
        return stIn.empty() && stOut.empty();
    }
};

 225.用队列实现栈操作

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

  • push(x) -- 元素 x 入栈
  • pop() -- 移除栈顶元素
  • top() -- 获取栈顶元素
  • empty() -- 返回栈是否为空

注意:

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

代码如下:

class MyStack {
public:
    //用一个对列
    queue<int,vector<int>>q;
    //弹出栈顶元素
    int pop() {
        int size = q.size();
        size--;//实际上,size先减1,就是为了队尾(也就是栈顶元素)在队列的最低下
        while (size--) {
            int top_q = q.front();
            q.push(top_q);  //不断弹出队首元素(只剩下原来的队尾)
            q.pop();//在 C++ 标准库中,std::queue 类的 pop() 函数是不接受任何参数的。pop() 函数用于在队列头部移除掉第一个元素,使得队列的大小减 1。函数没有返回值,处理完毕后队列被改变。
            //  因此,当使用 std::queue 类时,pop() 函数的括号里面不能填写任何参数,否则会出现编译错误。如果需要在队列中删除指定位置的元素,可以使用其他容器,如 std::list 或 std::deque,并使用其提供的 erase() 函数来实现。
        }
        int result = q.front();
        q.pop();
        return result;

    }
    //将x入栈
    void push(int x) {
        q.push(x);
    }
    //获取栈顶元素
    int top() {
        return q.back();
    }
    bool isempty() {
        return q.empty();
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值