【C++】Stack和Queue(初认识和算法题OJ)


栈(stack):后进先出的线性表

1. 核心特性

  • 全称:LIFO (Last In First Out,后进先出)
  • **数据只能从****栈顶(top)**插入、删除、访问
  • 不支持遍历、不支持随机访问、无迭代器
  • 典型场景:函数调用栈、括号匹配、表达式求值、浏览器后退

2. 底层默认容器

stack默认使用deque(双端队列)作为底层存储,也可手动指定vectorlist

3. stack的使用

函数 功能 时间复杂度
push(x) 向栈顶插入元素 x O(1)
pop() 删除栈顶元素(无返回值) O(1)
top() 获取栈顶元素(引用) O(1)
empty() 判断栈是否为空(空返回 true) O(1)
size() 获取栈中元素个数 O(1)

队列(queue):先进先出的线性表

1. 核心特性

  • 全称:FIFO (First In First Out,先进先出)
  • 数据从****队尾(back)插入,从队头(front)删除、访问
  • 同样不支持遍历、不支持随机访问、无迭代器
  • 典型场景:任务排队、消息队列、广度优先搜索 (BFS)、缓冲区

2. 底层默认容器

stack一致,queue默认底层容器也是deque,也可指定list(不能用 vector,因为 vector 不支持前端快速删除)。

3. queue的使用

函数 功能 时间复杂度
push(x) 向队尾插入元素 x O(1)
pop() 删除队头元素(无返回值) O(1)
front() 获取队头元素(引用) O(1)
back() 获取队尾元素(引用) O(1)
empty() 判断队列是否为空 O(1)
size() 获取队列元素个数 O(1)

算法题OJ

1.最小栈

155. 最小栈https://leetcode.cn/problems/min-stack/

pushpoptop 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

  • MinStack() 初始化堆栈对象。
  • void push(int val) 将元素val推入堆栈。
  • void pop() 删除堆栈顶部的元素。
  • int top() 获取堆栈顶部的元素。
  • int getMin() 获取堆栈中的最小元素。

题解:

cpp 复制代码
class MinStack {
    stack<int> st;
    stack<int> minStack;
public:
    MinStack() {
        st.push(INT_MAX);
    }
    
    void push(int val) {
        minStack.push(val);
        if(val<=st.top())
        st.push(val);
    }
    
    void pop() {
        if(minStack.top()==st.top())
        {
            minStack.pop();
            st.pop();
        }
        else
        minStack.pop();
    }
    
    int top() {
        return minStack.top();
    }
    
    int getMin() {
        return st.top();
    }
};

2.栈的压入和弹出序列

https://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106?https://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106?

列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。

  1. 0<=pushV.length == popV.length <=1000

  2. -1000<=pushV[i]<=1000

  3. pushV 的所有数字均不相同

题解:

cpp 复制代码
#include <iterator>
#include <stack>
class Solution {
public:
    bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {
       int ppop=0,ppush=0;
        stack<int> a1;
        if(pushV.size() != popV.size()) 
        {
            return false;
        }
        if(pushV.empty())
        {
            return false;
        }
        a1.push(pushV[ppush++]);
        while(ppop!=popV.size())
        {
            while(a1.top()!=popV[ppop])
            {  
                if(ppush==pushV.size())
                return false;
                a1.push(pushV[ppush++]);
            }
            while(a1.top()==popV[ppop])
            {
                ++ppop;
                a1.pop();
                if(ppop==popV.size())
                return true;
                if(a1.empty()&&ppush!=pushV.size())
                a1.push(pushV[ppush]);
            }
        } 
        return false;
 
    }
};

3.二叉树层序遍历

102. 二叉树的层序遍历https://leetcode.cn/problems/binary-tree-level-order-traversal/

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)

题解:

cpp 复制代码
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> nodeq;
        vector<vector<int>> res;
        int levelsize;//每层的结点个数
        if(root!=nullptr)
        nodeq.push(root);
        while(!nodeq.empty())
        {
            levelsize=nodeq.size();
            vector<int> tmp;//初始化放每层的结点的数据
            while(levelsize--)
            {
                TreeNode* p=nodeq.front();
                nodeq.pop();
                tmp.push_back(p->val);//不断取出队列头,放入tmp
                //放下一层的结点
                if(p->left!=nullptr)
                nodeq.push(p->left);
                if(p->right!=nullptr)
                nodeq.push(p->right); 
            }
            res.push_back(tmp);//把每层放入res
        }
        return res;
    }
};

4.后缀运算符

150. 逆波兰表达式求值https://leetcode.cn/problems/evaluate-reverse-polish-notation/

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

注意:

  • 有效的算符为 '+''-''*''/'
  • 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
  • 两个整数之间的除法总是 向零截断 。
  • 表达式中不含除零运算。
  • 输入是一个根据逆波兰表示法表示的算术表达式。
  • 答案及所有中间计算结果可以用 32 位 整数表示。

题解:

cpp 复制代码
class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> st;
        int n = 0, x = 0, sum = 0;
        char c;
        string d;
        while (n < tokens.size()) {
            //是不是数字
            d = (tokens[n]);
            if ((d[0] >= '0' && d[0] <= '9')||(d.size() > 1 && d[0] == '-'))
            {
                x = stoi(d);
                st.push(x);
            }
            //不是数字
            else {
                sum = st.top();
                st.pop();
                c=tokens[n][0];
                if (c == '+') {
                    st.top() += sum;
                } else if (c == '-') {
                    st.top() -= sum;
                } else if (c == '*') {
                    st.top() *= sum;
                } else {
                    st.top() /= sum;
                }
            }
            n++;
        }
        return st.top();
    }
};

5.双栈实现队列

232. 用栈实现队列https://leetcode.cn/problems/implement-queue-using-stacks/

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作( pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

题解:

cpp 复制代码
class MyQueue {
    stack<int> st1;
    stack<int> st2;
public:
    MyQueue() {
        
    }
    
    void push(int x) {
        st1.push(x);
    }
    
    int pop() {
        if(!st1.empty()&&st2.empty())
        {
            while(!st1.empty())
            {
               st2.push(st1.top());
               st1.pop(); 
            }   
        }
        int a=st2.top();
        st2.pop();
        return a;
    }
    
    int peek() { 
        if(st2.empty())
        {
            while(!st1.empty())
            {
               st2.push(st1.top());
               st1.pop(); 
            }
        }
        return st2.top();
    }
    
    bool empty() {
        return (st1.empty()&&st2.empty());
    }
};

相关推荐
ch.ju1 小时前
Java Programming Chapter 3——If the array is out of range
java·开发语言
枫叶丹41 小时前
【HarmonyOS 6.0】Desktop Extension Kit 正式接棒原状态栏服务,API 引用路径全面更新
开发语言·华为·harmonyos
fffzd1 小时前
C++入门(二)
开发语言·c++·算法·函数重载·引用·inline内联函数·nullptr
颜安青1 小时前
【python】运算符号(后续不断补充)
开发语言·python
傻瓜搬砖人1 小时前
c语言绿皮书第三版第十章习题
c语言·开发语言·算法
三块可乐两块冰1 小时前
rag笔记1
笔记
一只大袋鼠1 小时前
JavaWeb四种文件上传方式(上篇)
java·开发语言·servlet·javaweb
代钦塔拉1 小时前
Qt 按钮 Lambda 信号槽重复绑定、多次触发 BUG 深度剖析与终极解决方案
c++·qt·bug