【C++】stack、queue和优先级队列
一、前言
二、stack类
2.1 了解stack
2.2 使用stack
(1)empty
(2)size
(3)top
(4)push
(5)pop
2.3 stack的模拟实现
三、queue类
3.1 了解queue
3.2 使用queue
(1)empty
(2)size
(3)front
(4)back
(5)push
(6)pop
3.3 queue的模拟实现
四、优先级队列
4.1 了解优先级队列
4.2 使用优先级队列
(1)empty
(2)size
(3)top
(4)push
(5)pop
4.3 仿函数
4.4 优先级队列的模拟实现
五、deque类(了解)
5.1 关于deque
5.2 deque的应用
一、前言
通过前面的学习,我们已经对string、vector和list类有了了解
本文中介绍的stack、queue和优先级队列相比于前面的容器而言接口较少,并且有了前面的基础,在学习这几个容器的使用和模拟实现时会更好上手。
因此,本文仅对接口的使用进行简单介绍,把重点放在优先级队列等部分。
二、stack类
2.1 了解stack
stack - C++ Reference (cplusplus.com)https://legacy.cplusplus.com/reference/stack/stack/通过文档,我们可以了解到以下的内容:
- 区别于vector等容器,stack是一种容器适配器。通俗的讲,stack封装了一个其他的容器,并提供特定的成员函数来对容器进行操作并遵循栈的后进先出(Last-in First-out)原则。
- stack的底层容器至少要支持以下操作:
- empty:判空
- size:获取容器有效元素个数
- back:获取容器尾部元素
- push_back:尾插
- pop_back:尾删
- 通过这些操作,我们就可以实现栈的压入和弹出等行为
- 我们可以指定vector、list和deque作为stack的底层容器,如果没有指定,默认情况下使用deque,后面会对该容器进行介绍。
2.2 使用stack
在实例化与stack类类似的容器适配器时,模板参数除了必须要传入元素类型,还可以选择传入底层容器的种类
例如:
(1)empty
bool empty() const;
检测栈是否为空
(2)size
size_type size() const;
返回stack中元素的个数
(3)top
value_type& top();
const value_type& top(); const
返回栈顶元素的引用
(4)push
void push(const value_type& val);
将val压入栈中
(5)pop
void pop();
将栈顶元素弹出
例如:
2.3 stack的模拟实现
前面提到,stack是一个容器适配器,其底层封装了其他的容器,这里我们以vector作为底层容器
namespace Eristic
{template<class T, class Container = vector<T>> //一个模板参数传入数据类型,一个模板参数传入底层容器 class stack{public:void push(const T& val){_con.push_back(val); //压栈即在容器尾部插入数据}void pop(){_con.pop_back(); //出栈即删除容器尾部的数据}const T& top(){return _con.back(); //栈顶元素即容器尾部的元素}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con; //对容器进行封装};
}
三、queue类
3.1 了解queue
cplusplus.com/reference/queue/queue/https://cplusplus.com/reference/queue/queue/通过文档,我们可以了解到以下的内容:
- 队列也是一种容器适配器,对容器进行封装,提供特定的成员函数对容器进行操作并遵循队列的先进先出(First-in First-out)原则。
- 队列的底层容器至少要支持以下操作:
- empty:判空
- size:获取容器有效元素个数
- front:获取容器头部元素
- back:获取容器尾部元素
- push_back:尾插
- pop_front:头删
通过这些操作,我们就可以实现队列的出队和入队等行为。
- 我们可以指定list和deque作为queue的底层容器,如果没有指定,默认情况下使用deque
3.2 使用queue
(1)empty
bool empty() const;
检测队列是否为空
(2)size
size_type size() const;
返回队列中有效元素的个数
(3)front
value_type& front();
const value_type& front(); const
返回队头元素的引用
(4)back
value_type& back();
const value_type& (); const
(5)push
void push(const value_type& val);
从队尾将元素val入队列
(6)pop
void pop();
将队头元素出队列
例如:
3.3 queue的模拟实现
因为queue需要头删,如果底层使用vector效率太低,这里我们使用list作为queue的底层容器
namespace Eristic
{template<class T, class Container = list<T>>class queue{public:void push(const T& val){_con.push_back(val); //入队列,即从容器尾部插入数据}void pop(){_con.pop_front(); //出队列,即从容器头部删除数据}const T& front(){return _con.front();}const T& back(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};
}
四、优先级队列
4.1 了解优先级队列
cplusplus.com/reference/queue/priority_queue/https://cplusplus.com/reference/queue/priority_queue/
通过文档,我们可以了解到以下的内容:
- 优先级队列(priority_queue)是一种容器适配器,相比于普通队列,其内部每个元素都有一个优先级,所有元素按照优先级的顺序排列,优先级高的元素排在队头,优先级低的元素排在队尾。
- 优先级队列表现为一个顺序结构的完全二叉树,以堆的方式实现排序特性,因此优先级队列的底层容器需要支持随机迭代器访问,以便始终在内部保持堆结构。
- 优先级队列的底层容器至少要支持以下操作:
- empty:判空
- size:返回容器有效元素个数
- push_back:尾插
- pop_back:尾删
因为优先级队列以堆的方式实现,因此将数据出队列时应按照堆的方式删除数据,也就是首尾数据交换后尾删,并重新建堆。
- 我们可以指定vector和deque作为优先级队列的底层容器,如果没有指定,默认情况下使用vector。
4.2 使用优先级队列
(1)empty
bool empty() const;
检测优先级队列是否为空
(2)size
size_type size() const;
返回优先级队列中有效元素个数
(3)top
const value_type& top(); const
返回优先级队列中优先级最大的元素,即堆顶元素
(4)push
void push(const value_type& val);
向优先级队列中插入元素val
(5)pop
void pop();
删除优先级队列中优先级最大的元素,即堆顶元素
4.3 仿函数
可以看到,优先级队列相比stack和queue,又多了一个模板参数:仿函数。
首先,仿函数是一个类,而不是函数
当我们实例化优先级队列时不传入仿函数,就默认使用仿函数less,其效果为:
如果我们想变为升序,就需要手动传入仿函数greater,需要包含头文件<functional>
传入的仿函数为优先级队列提供了排序的顺序
仿函数在类中重载了括号(),使得我们可以像调用函数一样去调用实例化的类对象(或者匿名对象)。
我们以仿函数greater为例,自己尝试实现一个
template<class T>class greater{public:bool operator()(const T& x, const T& y){return x > y;}};
像这样,就是一个仿函数,而使用仿函数的方式如下:
可以看到,我们既可以使用仿函数实例化出的对象来调用类中的函数,也可以使用匿名对象调用。
4.4 优先级队列的模拟实现
namespace Eristic
{template<class T>class less //也可以用struct,默认公开{public:bool operator()(const T& x, const T& y){return x < y;}};template<class T>class greater{public:bool operator()(const T& x, const T& y){return x > y;}};template<class T, class Container = vector<T>, class Compare = less<T>>class priority_queue{public:void adjust_up(int child) //向上调整算法{Compare com;int parent = (child - 1) / 2;while (child > 0){if (com(_con[parent], _con[child])){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}elsebreak;}}void adjust_down(int parent) //向下调整算法{Compare com;int child = parent * 2 + 1;while (child < _con.size()){if (child + 1 < _con.size() && com(_con[child], _con[child + 1])){child++;}if (com(_con[parent], _con[child])){swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}elsebreak;}}void push(const T& x){_con.push_back(x); //队尾插入数据adjust_up(_con.size() - 1); //向上调整重新排序}void pop(){swap(_con[0], _con[_con.size() - 1]); //交换队头(堆顶)和队尾(堆尾)数据_con.pop_back(); //删除队尾数据adjust_down(0); //向下调整重新排序}const T& top(){return _con[0]; //取出队头(优先级最大)元素}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};
}
五、deque类(了解)
5.1 关于deque
deque(双端队列),是一种具有双向开口的连续线性空间的数据结构,在头尾插入的时间复杂度为常数,其特点介于vector和list之间。
双端数组的底层是一段假想的连续空间,看似所有元素是顺序排列的,实际上将元素分为了多块,每块元素之间依靠中控数组联系
中控数组是一个指针数组,存放了每个空间的指针
deque的整体结构如下:
这种结构相对于vector的优势在于,头插头删的效率和扩容的效率高,不需要移动大量元素,第一个元素会从中控数组的中间开始插入。
相对于list的优势在于,支持随机访问。
但是缺点在于中间的插入删除,如果我们规定指针指向的每个数组不一样大,那么中间插入删除的效率就较高,但是随机访问的效率会变差;如果规定数组一样大,随机访问的效率变高,但是同时会牺牲中间插入删除的效率。
问题又来了:既然deque支持随机访问,其迭代器是如何设计的呢?
其迭代器的设计如下:
其中,cur指向当前的位置,first指向小数组的开头,last指向小数组的结尾,node指向中控数组中指向数组的指针的位置。
当迭代器遍历到小数组的尾部,node走到下一个指针的位置,first和last更新,cur回到数组头部。
在这里引入deque的另一个缺陷:在遍历时,deque的迭代器需要频繁的去检测是否移动到小数组的边界,导致效率低下,而在序列式场景中需要经常的遍历容器。
5.2 deque的应用
虽然deque兼具了vector和list的特点,但是并没有做到极致,并且缺点也很明显,无法完全的替代vector和list,因此我们并不常用deque,其主要应用就是作为stack和queue的底层数据结构。
因为stack和queue只需要尾插或头插,并且不需要遍历,所以完美避免了deque的缺点,并且发挥了deque扩容效率和空间利用率高的优点。
完.
相关文章:
【C++】stack、queue和优先级队列
一、前言 二、stack类 2.1 了解stack 2.2 使用stack (1)empty (2)size (3)top (4)push (5)pop 2.3 stack的模拟实现 三、queue类 3.1 了解queue …...
第十三届蓝桥杯国赛真题 Java C 组【原卷】
文章目录 发现宝藏试题 A: 斐波那契与 7试题 B: 小蓝做实验试题 C: 取模试题 D: 内存空间试题 E \mathrm{E} E : 斐波那契数组试题 F: 最大公约数试题 G: 交通信号试题 I: 打折试题 J: 宝石收集 发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂&#x…...
docker部署ubuntu
仓库: https://hub.docker.com/search?qUbuntu 拉一个Ubuntu镜像 docker pull ubuntu:18.04 查看本地镜像: docker images 运行容器 docker run -itd --name ubuntu-18-001 ubuntu:18.04 通过ps命令可以查看正在运行的容器信息 docker ps 进入容器 最…...
iOS问题记录 - App Store审核新政策:隐私清单 SDK签名(持续更新)
文章目录 前言开发环境问题描述问题分析1. 隐私清单 & SDK签名1.1. 隐私清单 - 数据使用声明1.2. 隐私清单 - 所用API原因描述1.3. SDK签名 2. 即将发布的第三方SDK要求 解决方案最后 前言 前段时间用Flutter开发的iOS App提交了新版本,结果刚过两分钟就收到了…...
ES学习日记(二)-------集群设置
上一节写了elasticsearch单节点安装和配置,现在说集群,简单地说就是在多台服务器上搭建单节点,在配置文件里面增加多个ip地址即可,过程同单节点部署,主要说集群配置 注意:不建议在之前单节点es上修改配置为集群,据说运行之后会生成很多文件,在单点基础上修改容易出现未知问题,…...
农村集中式生活污水分质处理及循环利用技术指南
立项单位:生态环境部土壤与农业农村生态环境监管技术中心、山东文远环保科技股份有限公司、北京易境创联环保有限公司、中国环境科学研究院、广东省环境科学研究院、中铁第五勘察设计院集团有限公司、中华环保联合会水环境治理专业委员会 本文件规定了集中式村镇生活…...
linux 一些命令
文章目录 linux 一些命令fdisk 磁盘分区parted 分区文件系统mkfs 格式化文件系统fsck 修复文件系统 mount 挂载swap 交换分区清除linux缓存df du 命令raid 命令基本原理硬raid 和 软raid案例raid 10 故障修复,重启与卸载 lvm逻辑卷技术LVM的使用方式LVM 常见名词解析…...
移动硬盘损坏打不开?别急,这里有解决方案!
在日常工作和生活中,移动硬盘几乎成为了我们必不可少的存储设备,它小巧便捷,能够容纳大量的数据。然而,当移动硬盘突然损坏打不开时,那份焦虑与无助几乎无法用言语来形容。那些重要的文件、珍贵的照片,似乎…...
微信小程序【从入门到精通】——服务器的数据交互
👨💻个人主页:开发者-曼亿点 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 曼亿点 原创 👨💻 收录于专栏:…...
Python爬虫-懂车帝城市销量榜单
前言 本文是该专栏的第23篇,后面会持续分享python爬虫干货知识,记得关注。 最近粉丝留言咨询某汽车平台的汽车销量榜单数据,本文笔者以懂车帝平台为例,采集对应的城市汽车销量榜单数据。 具体的详细思路以及代码实现逻辑,跟着笔者直接往下看正文详细内容。(附带完整代码…...
《QDebug 2024年3月》
一、Qt Widgets 问题交流 1. 二、Qt Quick 问题交流 1.Qt5 ApplicationWindow 不能使用父组件 Window 的 transientParent 属性 ApplicationWindow 使用 transientParent 报错: "ApplicationWindow.transientParent" is not available due to compone…...
C# OpenCvSharp-HoughCircles(霍夫圆检测) 简单计数
目录 效果 项目 代码 下载 效果 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenCvSharp; using O…...
MybatisPlus速成
MybatisPlus快速入门 快速入门入门案例常见注解常见配置 核心功能条件构造器自定义SQLService接口 扩展功能代码生成静态工具逻辑删除枚举处理器JSON处理器 插件功能分页插件通用分页实体 参考文档 mybatis-plus参考文档 全部资料链接 讲义 快速入门 入门案例 <dependency…...
【Django开发】0到1美多商城项目md教程第4篇:图形验证码,1. 图形验证码接口设计【附代码文档】
美多商城完整教程(附代码资料)主要内容讲述:欢迎来到美多商城!,项目准备。展示用户注册页面,创建用户模块子应用。用户注册业务实现,用户注册前端逻辑。图形验证码,图形验证码接口设…...
八股 -- C#
面向对象 (三大特性) 三大特性目的是为了提供更好的代码组织、可维护性、扩展性和重用性 C#基础——面向对象 - 知乎 (zhihu.com) 封装 理解: 你不需要了解这个方法里面写了什么代码,你只需要了解这个方法能够给你返回什么数据&…...
科创新格局·共赢双循环“2024上海智能科技与创新展览会”
2024上海智能科技与创新展览会,将于6月中旬在上海新国际博览中心隆重召开。作为一场盛大的科技盛会,此次展览会将汇聚科技前瞻趋势,融合产业贸易优势,布局初创投资赛道,提供全方位场景生态的跨界合作,构建“…...
Chatopera 云服务的智能问答引擎实现原理,如何融合 #聊天机器人 技术 #Chatbot #AI #NLP
观看视频 Bilibili: https://www.bilibili.com/video/BV1pZ421q7EH/YouTube: https://www.youtube.com/watch?vx0d1_0HQa8o 内容大纲 提前在浏览器打开网址: Chatopera 云服务:https://bot.chatopera.comChatopera 入门教程:https://dwz…...
基于CNN-RNN的动态手势识别系统实现与解析
一、环境配置 为了成功实现基于CNN-RNN的动态手势识别系统,你需要确保你的开发环境已经安装了以下必要的库和工具: Python:推荐使用Python 3.x版本,作为主要的编程语言。TensorFlow:深度学习框架,用于构建…...
华为鲲鹏认证考试内容有哪些
华为鲲鹏认证考试的内容主要包括理论考核和实践考核两大部分。 在理论考核部分,主要考察考生对云计算、大数据、人工智能等相关领域的理论知识掌握情况,具体涉及体系结构、技术原理、应用场景等方面的内容。考生需要深入了解鲲鹏计算的特点,…...
Gitlab CI---could not read username for xxx: no such device or address
0 Preface/Foreword 项目开发中,经常会使用第三方的算法或者功能,那么就需要把对应的repo以子模块的方式添加到当前repo中。 添加命令: git submodule add <URL> 1 问题表现 子模块添加成功,但是GitLab CI阶段ÿ…...
三个AI创业方向各有特点和市场潜力
“AI 客户支持”乃成熟市场——B “AI 社交关系”属新旧交织之领域;——C “AI 企业知识”为专业化且对企业运营至要之领域——B AI 客户支持(Al customer support):此方向着重借助 AI 大模型技术,以改良和提升客户服务…...
C语言学习笔记二
文章目录 进制的代码表示数字数据类型字符类型输出字符例子 进制的代码表示 #include <stdio.h> int main() {short a 0100; // 八进制int b -0x1; // 十六进制long c 720; //十进制unsigned short m 0xffff; //十六进制unsigned int n 0x80000000; //十…...
Sublime Text4 4169 安装激活【亲测可用】
此教程用于Windows 下Sublime Text4 4169版本的安装和激活。 无需安装其他软件,无需下载替换文件,无需注册机等。 官网: https://www.sublimetext.com 下载地址 64位:https://download.sublimetext.com/sublime_text_build_41…...
【数据结构与算法初阶(c语言)】插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序、计数排序-全梳理(万字详解,干货满满,建议三连收藏)
目录 1.排序的概念及其运用 1.1排序的概念 1.2排序运用 1.3常见的排序算法 2.插入排序 2.1 原理演示:编辑 2.2 算法实现 2.3 算法的时间复杂度和空间复杂度分析 3.希尔排序 3.1算法思想 3.2原理演示 3.3代码实现 3.4希尔算法的时间复杂度 4.冒泡排序 4.1冒泡排…...
[蓝桥杯 2019 省赛 AB] 完全二叉树的权值
# [蓝桥杯 2019 省 AB] 完全二叉树的权值 ## 题目描述 给定一棵包含 $N$ 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是 $A_1,A_2, \cdots A_N$,如下图所示: 现在小明要把相同深度的节点的权值…...
亮数据Bright Data,引领高效数据采集新体验
随着互联网和大数据的日益普及,我们对于高速、安全和无限畅通的网络体验追求越发迫切,随之而来的网络安全和隐私保护变得越来越重要。IP代理作为一种实用的代理工具,可以高效地帮我们实现网络数据采集,有效解决网络安全问题&#…...
C#学习笔记
一、事件派发器 在C#中,事件派发器通常是指事件委托和事件处理程序的组合,用于实现一种观察者设计模式。它允许对象在状态发生变化时通知其他对象,从而实现对象之间的解耦。 事件派发器的基本组成部分: 事件委托(Ev…...
【A-006】基于SSH的新闻发布系统(含论文)
【A-006】基于SSH的新闻发布系统(含论文) 开发环境: Jdk7(8)Tomcat7(8)MySQLIntelliJ IDEA(Eclipse) 数据库: MySQL 技术: SpringStruts2HiberanteJSPJquery 适用于: 课程设计,毕业设计&…...
c语言-static
static作用:修饰变量和函数 修饰局部变量-静态局部变量 static未修饰局部变量 #include <stdio.h>void print() {int a 0;a;printf("%d ", a); }int main() {int i 0;for (i 0; i < 10; i){print();}return 0; }运行结果 static修饰局部变…...
zuul的性能调优
文章目录 zuul的性能调优Zuul参数剖析semaphore(信号量)ribbonhystrix高并发下常见Zuul异常熔断 zuul 1.x 与2.x的区别与总结 zuul的性能调优 在项目实践中,使用jemeter多线程并发访问微服务中的接口时候,在Zuul层出现异常、超时等,从而导致整…...
深圳盐田建设交易中心网站/优化推广公司哪家好
第4章 类和接口 类和接口是Java程序设计语言的核心,它们也是Java语言的基本抽象单元。Java语言提供了许多强大的基本元素,供程序员用来设计类和接口。 13. 使类和成员的可访问性最小化 要区别设计良好的模块与设计不好的模块,最重要的因素在于…...
上海黄页固定电话查询/seo网站优化工具大全
http://blog.csdn.net/cen616899547/article/details/38336185 在做rpg类游戏的过程中,经常遇到要判断周围怪物相对自身的方位 1.判断目标在自己的前后方位可以使用下面的方法: Vector3.Dot(transform.forward, target.position) 返回值为正时,目标在自己的前方,反之在自己的后…...
做动态图表的网站/口碑营销的例子
首先声明,此篇大部分内容转载于http://www.cnblogs.com/chenqf/p/6386163.html。作者这篇文章写的确实perfect。同时此篇内容再加一些自己的理解和补充。 彻底弄懂HTTP缓存机制及原理 前言 Http 缓存机制作为 web 性能优化的重要手段,对于从事 Web 开发的…...
做饲料推广哪个网站好/2345网址导航安装
随着MCU 种类不断的增多,我们可选择的范围也越来越大,以前很多做51 的朋友,又开始为自己寻找新的猎物了,MSP430 无疑成为他们的首选目标。因此,大多数程序员想轻松地实现过渡,那就是,把以前做的…...
十堰网站制作/潍坊百度关键词优化
系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、YOLOV1介绍二、YOLOV1网络结构三、YOLOV1检测流程四、YOLOV1的优劣势1.优势2.劣势参考资料前言 认知有限,望大…...
看设计案例的有哪些网站/2345中国最好的网址站
1、创建监听管理类 —————————————————– (java 架构师全套教程,共760G, 让你从零到架构师,每月轻松拿3万) 请加微信号:charlinsir, 下载请用百度盘 目录如下: 01.高级架构师四十二个阶段高 02.…...