栈(stack):后进先出的线性表
1. 核心特性
- 全称:LIFO (Last In First Out,后进先出)
- **数据只能从****栈顶(top)**插入、删除、访问
- 不支持遍历、不支持随机访问、无迭代器
- 典型场景:函数调用栈、括号匹配、表达式求值、浏览器后退
2. 底层默认容器
stack默认使用deque(双端队列)作为底层存储,也可手动指定vector、list。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/
持
push,pop,top操作,并能在常数时间内检索到最小元素的栈。实现
MinStack类:
MinStack()初始化堆栈对象。void push(int val)将元素val推入堆栈。void pop()删除堆栈顶部的元素。int top()获取堆栈顶部的元素。int getMin()获取堆栈中的最小元素。题解:
cppclass 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.栈的压入和弹出序列
列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
0<=pushV.length == popV.length <=1000
-1000<=pushV[i]<=1000
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,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)题解:
cppclass 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 位 整数表示。
题解:
cppclass 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/
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(
push、pop、peek、empty):实现
MyQueue类:
void push(int x)将元素 x 推到队列的末尾int pop()从队列的开头移除并返回元素int peek()返回队列开头的元素boolean empty()如果队列为空,返回true;否则,返回false题解:
cppclass 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()); } };

