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

【C++闯关笔记】STL:stack与queue的学习和使用

系列文章目录

上一篇文章:【C++闯关笔记】STL:list 的学习和使用-CSDN博客


文章目录

目录

前言

一、概念

二、使用介绍

1.stack:后进先出

核心特性

核心操作

细节与陷阱

使用场景

2.queue:先进先出

核心特性

核心操作

细节与陷阱

使用场景

三、模拟实现

1.stack模拟实现

2.queue模拟实现

总结



前言

C++中的stack、queue与数据结构中的栈、队列本质上是一样的,不同之处仅在C++将其它们封装成了类并添加了一些新东西,其他方面与数据的栈、队列完全一致。


一、概念

核心概念:它们都是“容器适配器”

首先,要建立一个重要的认知:stack 和 queue 都不是独立的容器,而是“容器适配器”

你可以把它们想象成对某种底层容器(如 list 、vector等 )的接口包装和功能限制。它们基于vector、list 或者其他什么底层容器构建,但只暴露了符合特定数据结构(栈或队列)规则的接口。

二、使用介绍

1.stack:后进先出

核心特性

①LIFO: Last-In, First-Out,后进先出。就像一摞盘子,取的总是最上面的那个(也就是最后放上去的)。

②栈顶:我们约定进行操作的那一端称为栈顶,另一端则为栈底。

核心操作

  • push(const T& value)压栈,将元素放入栈顶。

  • pop()弹栈,移除栈顶元素(并不返回元素!)。

  • top()访问栈顶元素(返回引用)。

  • empty(): 判断栈是否为空。

  • size(): 返回栈中元素个数。

细节与陷阱

①pop( ) 返回 void,不能用来获取值。正确的做法是先通过top( )获取栈顶数据,在pop( )移除栈顶数据;

②警惕空栈。对空栈调用top 和pop 操作是未定义行为,绝大多数情况下会导致程序崩溃;

使用场景

  • 函数调用栈:计算机系统最核心的应用,记录函数调用关系和局部变量。

  • 表达式求值:处理括号匹配、将中缀表达式转换为后缀表达式。

  • 撤销操作:编辑器中的撤销,将操作压栈,撤销时弹出。

  • 深度优先搜索:DFS算法通常使用栈来实现。

2.queue:先进先出

核心特性

①FIFO: First-In, First-Out,先进先出。就像现实生活中的排队,先来的人先接受服务。

②出数据的一端称为队头入数据的一端称为队尾

核心操作

  • push(const T& value)入队,将元素放入队尾。

  • pop()出队,移除队首元素(同样不返回元素!)。

  • front()访问队首元素。

  • back()访问队尾元素。

  • empty(): 判断队列是否为空。

  • size(): 返回队列中元素个数。

细节与陷阱

①front()/back() 和 pop() 也必须分两步走。先通过 front / back 获取数据后,再 pop 出数据。

警惕空队列。对空队列调用 front()/back() 和 pop() 同样是未定义行为

使用场景

  • 广度优先搜索:BFS算法的核心数据结构。

  • 消息队列:在网络通信或多线程中,用于在不同线程或进程间传递数据。

  • 缓冲区:例如打印机任务队列,先提交的打印任务先执行。

  • 模拟现实排队:银行叫号系统等。


三、模拟实现

1.stack模拟实现

考虑到 stack 只在栈顶频繁进行数据的写入写出,那么选择一个插入/删除数据操作效率高的底层容器,进行封装无疑是最好的选择。

vector 的push_back与push_pop 时间复杂度均为O(1),故这里我们采用封住 vector 来模拟实现stack。

模拟代码如下:

#include <vector>namespace karsen
{template<typename T>class stack{public:stack(){}void push(const T& x){_st.push_back(x);}T& top(){return _st.back();}bool empty(){return _st.empty();}size_t size(){return _st.size();}void pop(){_st.pop_back();}private:std::vector<T> _st;};
}

2.queue模拟实现

相较于 stack 的单侧数据增删,queue需要在队头/队尾频繁进行数据增删,vector 显然不再适合,此时本质为双向循环链表的 list 就比较合适。

模拟代码如下:

#pragma once
#include<list>namespace karsen
{template<typename T>class queue{public:queue(){}bool empty(){return _qu.empty();}void push(const T& x){_qu.push_back(x);}void pop(){_qu.pop_front();}T& back(){return _qu.back();}T& front(){return _qu.front();}size_t size(){return _qu.size();}private:std::list<T> _qu;};};

总结

本文介绍了stack与queue的概念以及使用,最后给出了 vector 模拟实现的stack代码;用 list 模拟实现的 queue代码。

值得一提的是STL源码中,stack与queue都是基于deque进行封装的,deque不仅提供O(1)的头尾操作,并且没有vector扩容时带来的时间损耗。

最后,如果希望进一步探究栈与队列的使用,可参考:

【数据结构】栈_栈 数据结构-CSDN博客

【数据结构】队列_数据结构队列-CSDN博客

读完点赞,手留余香~

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

相关文章:

  • [HCTF 2018] WarmUp
  • Vue 学习随笔系列二十六 —— 动态表头
  • BIM 可视化运维平台 + IBMS 中央集成系统一体化解决方案:构建虚实融合的智慧运营中枢
  • XSUN_DESKTOP_PET(桌面宠物)
  • 具身智能VR遥操开发记录
  • 构建AI智能体:三十八、告别“冷启动”:看大模型如何解决推荐系统的世纪难题
  • [重学Rust]之结构体打印和转换
  • 数据结构(陈越,何钦铭) 第十一讲 散列查找
  • 2025年JBD SCI2区TOP,基于改进蚁群算法的应急路径规划,深度解析+性能实测
  • UIKit-layer
  • 一物一码公司推荐再互动平台
  • Wireshark捕获MQTT报文
  • Docker镜像核心作战手册:镜像命令全解析+离线迁移实战+压缩共享储存,打造无缝跨环境部署!
  • Static Deinitialization Order Fiasco
  • 如何使用 Qt Creator 高效调试
  • 保障路灯用电安全!配电箱漏电检测,为城市照明筑牢防线
  • 不同版本tensorflow推理报错解决方法
  • 嵌入式铁头山羊STM32-各章节详细笔记-查阅传送门
  • 在没有随机对照的情况下如果做实验对比:双重差分法(结合虚拟变量回归)(五)
  • 材质、效率双突破:Rendercool 解决室内渲染核心痛点
  • 【ThreeJs】【材质Material】核心材质参数解析手册
  • 无人机桨叶的材质与工艺对飞行速度的影响
  • PMBOK第六版项目沟通管理总结
  • fatal: Need to specify how to reconcile divergent branches.原因及解决方案
  • 二叉树与二叉搜索树(BST):从基础到应用
  • 【一天一个Web3概念】区块链分叉(Fork)全面解析:类型、案例与影响
  • PHP低代码工作流创新,为企业数字化转型添翼
  • 低代码+AI生态:企业数字化起步阶段的“核聚变”冲击波
  • 【Linux基础知识系列:第一百三十四篇】理解Linux的进程调度策略
  • 主机windows虚拟机centos的hadoop调试mapreduce访问hdfs文件