当前位置: 首页 > news >正文

深入理解栈与队列:核心特性与实战应用

🔥个人主页:胡萝卜3.0

📖个人专栏:  《C语言》、《数据结构》 、《C++干货分享》、LeetCode&牛客代码强化刷题

⭐️人生格言:不试试怎么知道自己行不行


🎥胡萝卜3.0🌸的简介:


目录

一. 先搞懂基础:Stack 与 Queue 的核心特性

二、栈(Stack):受限的“单口管道”操作

2.1 核心特性:

2.2 stack核心接口使用

2.2.1 创建stack对象

2.2.2 常用接口

三、队列(Queue):先进先出的公平性规则

3.1 核心特性:

3.2 核心接口使用

3.2.1 创建queue对象

3.2.2 常用接口

四、实战训练题

4.1 最小栈

4.2 栈的压入、弹出序列

4.3 逆波兰表达式求值

4.4 二叉树的层序遍历


一. 先搞懂基础:Stack 与 Queue 的核心特性

在写代码前,首先要明确两者的 “数据访问规则”—— 这是它们区别于其他容器的关键:

容器核心规则访问特性
stack后进先出(LIFO)仅能访问“栈顶”元素
queue先进先出( FIFO)仅能访问“队头”和“堆尾”元素

两者的共同特性是:不支持下标访问和迭代器

二、栈(Stack):受限的“单口管道”操作

2.1 核心特性:

  • 访问规则:只能从"栈顶"添加或删除元素(最后入栈的元素最先出栈)
  • 适用场景:函数调用栈,表达式求值等。

参考文档:stack - C++ Reference

2.2 stack核心接口使用

2.2.1 创建stack对象

这里就很直接上代码演示~~

#include<iostream>
#include<stack>
#include<vector>
#include<list>
using namespace std;
void testStack1()
{//定义栈:默认存储int类型,底层依赖deque实现stack<int> st1;//可指定底层容器(如vector、list)stack<int, vector<int>> st2;stack<int, list<int>> st2;
}

stack 是一个容器适配器,我们可以根据需求选择最合适的底层容器。

  • 选择 std::vector:可能获得更好的缓存局部性,但动态扩展时可能需要重新分配内存。

  • 选择 std::deque(默认):首尾插入删除效率都高,不需要大量的内存重新分配。

  • 选择 std::list:在中间插入删除效率高(虽然栈用不到),但内存开销稍大。

2.2.2 常用接口
函数说明接口说明
stack()构造空的栈
push()将元素val压入stack中
pop()出栈操作
top()返回栈顶元素的引用
empty()检测stack是否为空
size()返回stack中元素的个数

这些接口的使用很简单,我们快速演示一下:

  • stack()

创建一个空的栈

void testStack1()
{//定义栈:默认存储int类型,底层依赖deque实现stack<int> st1;//可指定底层容器(如vector、list)stack<int, vector<int>> st2;stack<int, list<int>> st3;
}
  • push()

将数据压入栈中

void testStack1()
{	stack<int> st1;//压栈st1.push(1);st1.push(2);st1.push(3);st1.push(4);st1.push(5);
}
  • top()

取栈顶元素

void testStack1()
{	stack<int> st1;//压栈st1.push(1);st1.push(2);st1.push(3);st1.push(4);st1.push(5);//取栈顶元素int ret = st1.top();cout << ret << endl;
}
  • pop()

出栈

void testStack1()
{	stack<int> st1;//压栈st1.push(1);st1.push(2);st1.push(3);st1.push(4);st1.push(5);//取栈顶元素int ret = st1.top();cout << ret << endl;//打印结果:5//出栈st1.pop();//取栈顶元素ret = st1.top();//打印结果:4cout << ret << endl;
}
  • size()

求出栈中的有效数据个数

void testStack1()
{	stack<int> st1;//压栈st1.push(1);st1.push(2);st1.push(3);st1.push(4);st1.push(5);//求出有效数据个数size_t _size = st1.size();cout << _size << endl;
}
  • empty()

判断栈是否为空,栈为空返回true,栈不为空返回false

void testStack1()
{	stack<int> st1;//压栈st1.push(1);st1.push(2);st1.push(3);st1.push(4);st1.push(5);//判断栈是否为空bool ret = st1.empty();cout << ret << endl;//输出结果为0,说明栈不为空
}

三、队列(Queue):先进先出的公平性规则

3.1 核心特性:

  • 访问规则:从"队尾"添加元素,从"队头"删除元素(最先入队的元素最先出队)
  • 适用场景:任务调度(如打印队列)、消息队列、广度优先搜索(BFS)等

参考文档:queue - C++ Reference

3.2 核心接口使用

3.2.1 创建queue对象
void testQueue1()
{//定义队列:默认底层依赖deque实现queue<int> q;//可指定底层容器(如list,不能使用vector,std::vector 不支持 pop_front() 操作)queue<int, list<int>> q2;
}
3.2.2 常用接口
函数声明接口说明
empty()检测队列是否为空,是返回true,否则返回false
size()返回队列中有效元素的个数
front()返回队头元素的引用
back()返回队尾元素的引用
push()在队尾将元素val入队列
pop()将队头元素出队列
  • push()

从队尾入队列

void testQueue1()
{queue<int> q;//入队q.push(1);q.push(2);q.push(3);q.push(4);q.push(5);while (!q.empty()){cout << q.front() << " ";q.pop();}
}
  • pop()

从队头出数据

void testQueue1()
{queue<int> q;//入队q.push(1);q.push(2);q.push(3);q.push(4);q.push(5);//出队q.pop();
}
  • front()

返回队头元素的引用

void testQueue1()
{queue<int> q;//入队q.push(1);q.push(2);q.push(3);q.push(4);q.push(5);//返回队头元素的引用int _front = q.front();cout << _front << endl;
}
  • back()

返回队尾元素的引用

void testQueue1()
{queue<int> q;//入队q.push(1);q.push(2);q.push(3);q.push(4);q.push(5);//返回队尾元素的引用int _back = q.back();cout << _back << endl;
}
  • size()

求出有效数据个数

void testQueue1()
{queue<int> q;//入队q.push(1);q.push(2);q.push(3);q.push(4);q.push(5);//有效数据个数size_t _size = q.size();cout << _size << endl;
}
  • empty()

判断队列是否为空

void testQueue1()
{queue<int> q;//入队q.push(1);q.push(2);q.push(3);q.push(4);q.push(5);//判断队列是否为空bool ret = q.empty();cout << ret << endl;
}

ok,stack和queue的使用就说到这里,接下来我们来做几个题

四、实战训练题

4.1 最小栈

  • 题目链接

155. 最小栈

  • 题目描述:

  • 解题思路:

  • 代码演示:
class MinStack {
public://这里的构造不用写,默认生成的构造会去调用stack中的构造MinStack() {}void push(int val) {_str.push(val);if(_minstr.empty()||_str.top()<=_minstr.top()){_minstr.push(val);}}void pop() {if(_str.top()==_minstr.top()){_minstr.pop();}_str.pop();}int top() {return _str.top();}int getMin() {return _minstr.top();}private:stack<int> _str;stack<int> _minstr;
};

4.2 栈的压入、弹出序列

  • 题目链接:

栈的压入、弹出序列_牛客题霸_牛客网

  • 题目描述:

简单来说:就是判断出栈顺序是否和提供的出栈顺序是相同的,相同返回true,不相同返回false

  • 解题思路:

  • 代码演示:
class Solution {
public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param pushV int整型vector * @param popV int整型vector * @return bool布尔型*/bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {size_t posh=0,posp=0;stack<int> st;while(posh < pushV.size()){st.push(pushV[posh]);while(!st.empty()&&st.top()==popV[posp]){st.pop();posp++;}//跳出循环,说明不相等了,继续入栈posh++;}return st.empty();}
};

4.3 逆波兰表达式求值

  • 题目链接

150. 逆波兰表达式求值 - 力扣(LeetCode)

  • 题目描述:

  • 解题思路:

  • 代码演示:
class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;for(auto& e:tokens){if(e=="+"||e=="-"||e=="*"||e=="/"){//操作符,进行运算操作int right=st.top();st.pop();int left=st.top();st.pop();switch(e[0]){case '+':st.push(left+right);break;case '-':st.push(left-right);break;case '*':st.push(left*right);break;case '/':st.push(left/right);break; }}else{//操作数//stoi:将整型字符转成整型intst.push(stoi(e));}}return st.top();}
};

4.4 二叉树的层序遍历

  • 题目链接

102. 二叉树的层序遍历 - 力扣(LeetCode)

  • 题目描述:

  • 解题思路:

每次只出当前层的元素,出之前把它的左右孩子插入栈中,等到当前层的出完出去之后更新levelSize,此时刚好等于现在栈中的元素个数。

  • 代码演示:
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> q;size_t levelSize;if(root){q.push(root);levelSize=1;}vector<vector<int>> vv;//一层一层的出while(!q.empty()){vector<int> v;//一层一层的出while(levelSize--){TreeNode* _front=q.front();v.push_back(_front->val);//让不为空的左右孩子入队列q.pop();if(_front->left){q.push(_front->left);}if(_front->right){q.push(_front->right);}}vv.push_back(v);levelSize=q.size();}return vv;}
};

http://www.dtcms.com/a/519776.html

相关文章:

  • 如何建一个免费的网站南昌做网站优化哪家好
  • 机器学习概念,算法原理及应用
  • Pytorch常用层总结
  • 【Deepseek OCR】重磅测试,mac环境下的体验【本人已经本地实验成功】
  • 轻量化(Lightweight)概念
  • [人工智能-大模型-58]:模型层技术 - 深度神经网络的本质是一个复杂的复合数学函数
  • 【小白笔记】将十进制数(Decimal)转换为二进制数(Binary),并计算二进制表示中“1”的个数
  • 长春怎么注册网站平台wordpress 视频列表
  • 【ReAcTable】面向表格问答任务的ReAct增强框架
  • Docker 部署 Elasticsearch 全流程手册
  • React 集成Redux数据状态管理 数据共享 全局共享
  • Docker与Nginx:现代Web部署的完美二重奏
  • 【JUnit实战3_08】第四章:从 JUnit 4 迁移到 JUnit 5
  • React 03
  • 前端基础之《React(2)—webpack简介-使用Babel》
  • 广州网站建设公司嘉御建设手机银行网站
  • 【Linux系统编程】软件包管理器
  • 怎么快速定位bug?如何编写测试用例?
  • NetIP,一款开源的快速网络信息查看工具
  • 有限元方法核心原理与学习路径:从一维基础到多维拓展(七步流程)
  • TCP(滑动窗口/拥塞窗口补充)
  • nginx前端部署与Vite环境变量配置指南
  • webrtc getStats 内部调用流程分析
  • 通过 Stdio(标准输入/输出)传输机制,实现 CrewAI 与本地 MCP 服务器的连接
  • 英文版网站建设方案手机app免费制作
  • 通过API网关部署FC函数
  • 单例模式精写
  • SQL sever数据库--第三次作业
  • XLM-R模型:大规模跨语言表示的突破与实践
  • GitLab 多安全漏洞可致攻击者触发拒绝服务状态