《STL--stack 和 queue 的使用及其底层实现》

article/2025/6/16 19:51:12

引言:

上次我们学习了容器list的使用及其底层实现,相对来说是比较复杂的,今天我们要学习的适配器stackqueuelist相比就简单很多了,下面我们就开始今天的学习:

一:stack(后进先出)

1. 约定:

由于之前我们在数据结构初阶阶段已经了解过stack这个容器了,因此这里就不再具体来介绍了。

2. stack的介绍

stack的介绍文档

3. stack的使用

  1. stack(): 构造一个空栈。
  2. empty():判断栈是否为空。
  3. size():返回栈中的数据个数。
  4. top():返回栈顶数据。
  5. push():将元素压入栈中。
  6. pop():将栈顶元素弹出栈。

代码演示:

在这里插入图片描述

二:queue(先入先出)

1. 约定:

由于之前我们在数据结构初阶阶段已经了解过queue这个容器了,因此这里就不再具体来介绍了。

2. queue的介绍:

queue的介绍文档

3. queue的使用:

  1. queue(): 构造一个空队列 。
  2. empty(): 判断队列是否为空。
  3. size(): 返回队列中数据个数。
  4. push(): 将数据加入队列。
  5. pop(): 将队头数据出队。
  6. front(): 返回队头数据。
  7. back(): 返回队尾数据。

代码演示:

在这里插入图片描述

三:priority_queue

1. 约定:

这里的priority_queue就可以对比之前我们在数据结构初阶的时候学习的堆,因此这里的priority_queue也就不作具体介绍了。

2. priority_queue的介绍:

优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue
默认情况下priority_queue是大堆 。
priority_queue的具体介绍文档

3. priority_queue的使用:

  1. priority_queue():构造一个空的堆。
  2. priority_queue(first,last): 用迭代器区间构造一个优先队列。
  3. empty(): 判断堆是否为空。
  4. top(): 返回堆顶数据。
  5. push(): 将数据入堆。
  6. pop(): 删除堆顶数据。

代码演示:

1. 普通构造:

在这里插入图片描述
注:这里的数据构成二叉树的话是满足大根堆的。

2. 迭代器构造:

在这里插入图片描述

3. 自定义实现大根堆、小根堆

对于内置类型的话:
如果这里我想要创建小根堆的话就需要自己传入仿函数来实现:
在这里插入图片描述

如果是自定义类型的话,创建大根堆小根堆都需要有相应的< >运算符重载,下面拿日期类来举例:
这是我们实现的一个日期类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四:priority_queue 的模拟实现

1. 仿函数:

(1)定义:

仿函数(Functor),也称为函数对象(Function Object),是C++中通过重载operator()运算符的类或结构体,使其能够像函数一样被调用。

(2)形式:

注:我们这里的仿函数写成了模版的形式,契合泛型编程的思想,适用范围更广。
这是我们实现的一个小于的仿函数:
在这里插入图片描述
这是我们实现的一个大于的仿函数:
在这里插入图片描述

2. 基本框架:

注:这里我们是按照大根堆来实现的,想实现小根堆只需修改第三个参数即可。
在这里插入图片描述
注:这里的第二个参数container和第三个参数compare别忘了实例化。

3. 向上调整算法:

在这里插入图片描述

4. 向下调整算法:

在这里插入图片描述

5. 入堆:

在这里插入图片描述

6. 出堆:

在这里插入图片描述

7. 取堆顶:

在这里插入图片描述

8. 判空:

在这里插入图片描述

9. 求数据个数:

在这里插入图片描述

10. 测试:

在这里插入图片描述

五:容器适配器

1. 定义:

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。

2. STL标准库中stack和queue的底层结构:

虽然stackqueue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stackqueue只是对其他容器的接口进行了包装,STLstackqueue默认使用deque,比如:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到上面的这几个数据结构都是其他容器的封装。

3. deque(了解)

(1)原理介绍:

deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。
在这里插入图片描述
deque并不是真正意义上的连续空间,而是由一段段连续空间连接起来的,类似于一个动态的二维数组。

其底层结构如下图:
在这里插入图片描述
它的底层实现比较复杂(不需要深入学习)

双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问的假象,这个责任就落在了deque的迭代器身上,因此deque的迭代器设计就比较复杂,如下图所示:
在这里插入图片描述
在这里插入图片描述

4. deque的缺陷:

vector比较,deque的优势是:头部插入删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是比vector高的。
list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。

但是,deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vectorlistdeque的应用并不多,而目前能看到的一个应用就是,STL用其作为stackqueue的底层数据结构。

5. 思考:为什么选择deque作为stack和queue的底层默认容器?

stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()pop_back()操作的线性结构,都可以作为stack的底层容器,比如vectorlist都可以;queue是先进先出的特殊线性数据结构,只要具有push_backpop_front操作的线性结构,都可以作为queue的底层容器,比如list。但是STL中对stackqueue默认选择deque作为其底层容器,主要是因为:

  1. stackqueue不需要遍历(因此stackqueue没有迭代器),只需要在固定的一端或者两端进行操作。
  2. stack中元素增长时,dequevector的效率高(扩容时不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且内存使用率高。结合了deque的优点,而完美的避开了其缺陷(不需要随机访问,避免了频繁调动[])。

六:stack的模拟实现

1. 基本框架:

在这里插入图片描述

2. 入栈:

在这里插入图片描述

3. 出栈:

在这里插入图片描述

4. 取栈顶:

在这里插入图片描述

5. 求栈中数据个数:

在这里插入图片描述

6. 判空:

在这里插入图片描述

7.测试:

在这里插入图片描述
在这里插入图片描述

七:queue的模拟实现:

1. 基本框架:

在这里插入图片描述

2. 入队:

在这里插入图片描述

3. 出队:

在这里插入图片描述

4. 取队头数据:

在这里插入图片描述

5.取队尾数据:

在这里插入图片描述

6. 求队列中数据个数:

在这里插入图片描述

7. 判空:

在这里插入图片描述

8. 测试:

在这里插入图片描述

完结!!!


http://www.hkcw.cn/article/mpBJYOcvcU.shtml

相关文章

Redis缓存问题重点详解

前言&#xff1a;本节包含常见redis缓存问题&#xff0c;包含缓存一致性问题&#xff0c;缓存雪崩&#xff0c;缓存穿透&#xff0c;缓存击穿问题及其解决方案 1. 缓存一致性 我们先看下目前企业用的最多的缓存模型。缓存的通用模型有三种&#xff1a; 缓存模型解释Cache Asi…

Redis最佳实践——安全与稳定性保障之访问控制详解

Redis 在电商应用的安全与稳定性保障之访问控制全面详解 一、安全访问控制体系架构 1. 多层级防护体系 #mermaid-svg-jpkDj2nKxCq9AXIW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-jpkDj2nKxCq9AXIW .error-ico…

矩阵快速幂算法快速上手

矩阵快速幂算法快速上手 一、基础知识回顾1.1 矩阵乘法1.2 单位矩阵 二、快速幂算法思想2.1 整数快速幂2.2 矩阵快速幂 三、矩阵快速幂的代码实现3.1 Python实现3.2 C实现3.3 Java实现 四、矩阵快速幂的应用场景4.1 斐波那契数列4.2 线性递推数列4.3 图论中的路径计数4.4 动态规…

外国人眼中的端午赛龙舟 文化共鸣与体验

当地人教恩佐包香囊,黄春隆体验划龙舟,罗珃身着汉服,沉浸式体验端午文化后拍照留念。吃粽子、赛龙舟、做香囊……外国友人对端午文化有多少了解?哪些端午习俗令他们印象深刻?恩佐来自法国中部卢瓦雷省的小城蒙塔日,他的家乡与中国渊源已久,是邓小平年轻时曾经勤工俭学的…

博主:登贝莱预定金球奖 欧冠决赛闪耀

巴黎圣日耳曼在欧冠决赛中以5-0大胜国米,首次夺得冠军。奥斯曼-登贝莱为队友送出了两次助攻。《队报》认为,他比以往任何时候都更有希望角逐2025年金球奖。作为俱乐部主席,纳赛尔-阿尔赫莱菲按惯例出现在颁奖台上,紧紧拥抱了奥斯曼-登贝莱,并在他耳边低语。这位卡塔尔人脸…

uniapp调试,设置默认展示的toolbar内容

uniapp调试&#xff0c;设置默认展示的toolbar内容 设置pages.json中 pages数组中 json的顺序就可以只需要调整顺序&#xff0c;不会影响该bar在页面中的显示默认展示第一条page

设计模式——适配器设计模式(结构型)

摘要 本文详细介绍了适配器设计模式&#xff0c;包括其定义、核心思想、角色、结构、实现方式、适用场景及实战示例。适配器模式是一种结构型设计模式&#xff0c;通过将一个类的接口转换成客户端期望的另一个接口&#xff0c;解决接口不兼容问题&#xff0c;提高系统灵活性和…

元胞自动机(Cellular Automata, CA)

一、什么是元胞自动机&#xff08;Cellular Automata, CA&#xff09; 元胞自动机&#xff08;CA&#xff09; 是一种基于离散时间、离散空间与规则驱动演化的动力系统&#xff0c;由 冯诺依曼&#xff08;John von Neumann&#xff09; 于1940年代首次提出&#xff0c;用于模…

华为OD机试真题——模拟消息队列(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 2025华为OD真题目录+全流程解析/备考攻略/经验分享 华为OD机试真题《模拟消息队列》: 目录 题…

Nacos 配置文件总结

Nacos 配置文件总结 文章目录 Nacos 配置文件总结1 、在 Nacos 服务端添加配置文件1. 启动Nacos Server。2. 新建配置文件。3. 发布配置集后&#xff0c;我们便可以在配置列表中查看相应的配置文件。4. 配置nacos数据库5. 运行 Nacos 容器6. 验证安装结果7. 配置验证 2 、在 Na…

一文读懂MCP模型上下文协议

前言&#xff1a;MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;作为一个全新的开源协议框架被提出&#xff0c;它试图重塑模型开发、集成与协作的方式。MCP让只能人机交互的大模型转化为了能够快速对接各类业务系统的生产力大脑。传统做法通常…

C#数字图像处理(一)

文章目录 1.C#图像处理基础1.1 Bitmap类1.2 Bitmapdata类1.3 Graphics类1.4 Image类 2.彩色图像灰度化1.提取像素法2.内存法3.指针法三种方法的比较4.灰度图像二值化&#xff1a; 3.相关链接 Bitmap类、 Bitmapdata类和 Graphics类是C#图像处理中最重要的3个类,如果要用C# 进行…

各种数据库,行式、列式、文档型、KV、时序、向量、图究竟怎么选?

慕然回首&#xff0c;发现这些年来涌现出了许多类型的数据库&#xff0c;今天抽空简单回顾一下&#xff0c;以便于后面用到时能快速选择。 1. 关系型数据库(行式) 关系型数据库&#xff08;RDBMS&#xff09;&#xff0c;我们常说的数据库就是指的关系型数据库。 它的全称是关…

uView UI的使用

1. uView UI 封装了request.get登方法请求&#xff0c;异步调用。 故需可以使用then, catch, finally uView UI. 是一个专为UniApp设计的跨平台UI框架, 注意这里是跨平台&#xff0c;也就是可以再IOS, ANDROID 机器上运行的框架 2. easycom 词面意思容易使用的组件 在使用…

win32相关(临界区)

临界区 每个线程都有自己的栈&#xff0c;而局部变量是存在在栈中的&#xff0c;这就意味着每个线程都有一份自己的”局部变量“&#xff0c;如果线程仅仅只是使用自己的”局部变量“那么就不会有线程安全问题&#xff0c;那如果多个线程使用一个全局变量呢&#xff1f; 我们用…

UE5蓝图暴露变量,在游戏运行时修改变量实时变化、看向目标跟随目标Find Look at Rotation、修改玩家自身弹簧臂

UE5蓝图中暴露变量&#xff0c;类似Unity中public一个变量&#xff0c;在游戏运行时修改变量实时变化 1&#xff0c;添加变量 2&#xff0c;设置变量的值 3&#xff0c;点开小眼睛&#xff0c;此变量显示在编辑器中&#xff0c;可以运行时修改 看向目标跟随目标Find Look at R…

112 Gbps 及以上串行链路的有效链路均衡

通道均衡已成为当今高速串行链路的关键机制。目前有许多均衡方案&#xff0c;例如发射机加重均衡、接收机CTLE&#xff08;连续时间线性均衡器&#xff09;、FFE&#xff08;前馈均衡器&#xff09;、DFE&#xff08;判决反馈均衡器&#xff09;和FEC&#xff08;前向纠错&…

【LLM相关知识点】关于LangChain框架学习简单整理(三)

【LLM相关知识点】关于LangChain框架学习简单整理&#xff08;三&#xff09; 一、核心模块和协作模式 参考极简LangChain智能体开发入门指南&#xff0c;LangChain官方文档 LangChain核心模块与功能&#xff1a; 核心模块功能描述关键技术点​模型I/O管理大模型输入输出&a…

基于CangjieMagic的RAG技术赋能智能问答系统

目录 引言 示例程序分析 代码结构剖析 导入模块解读 智能体配置详情 提示词模板说明 主程序功能解析 异步聊天功能实现 检索信息展示 技术要点总结 ollama 本地部署nomic-embed-text 运行测试 结语 引言 这段时间一直在学习CangjieMagic。前几天完成了在CangjieMa…

【速通RAG实战:进阶】18、如何利用LLM记忆功能,实现一对一的个性化服务

一、赛博记忆的本质:从数据到数字人格的进化 (一)核心概念与技术定位 赛博记忆(Cyber Memory)是通过AI技术将个人多源数据(文本、图像、生物特征等)转化为可交互的动态记忆系统,其终极目标是构建可进化的数字人格,实现记忆的存储、重构与智能响应。与传统数据存储不…