C++笔记10•容器适配器:stackqueue priority_queue•

从C++中看stack&queue&priority_queue

1.stack的介绍

官方stack实现: 本质是一个数组
1. stack 是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。
2. stack 是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部( 即栈顶 ) 被压入和弹出。
3. stack 的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下
操作:
empty :判空操作
back :获取尾部元素操作
push_back :尾部插入元素操作
pop_back :尾部删除元素操作
4. 标准容器 vector deque list 均符合这些需求,默认情况下,如果没有为 stack 指定特定的底层容器, 默认情况下使用deque

2. queue的介绍

官方queue实现:本质是一个链表
1. 队列是一种容器适配器,专门用于在 FIFO 上下文 ( 先进先出 ) 中操作,其中从容器一端插入元素,另一端提取元素。
2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类, queue 提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。
3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:
empty :检测队列是否为空
size :返回队列中有效元素的个数
front :返回队头元素的引用
back :返回队尾元素的引用
push_back :在队列尾部入队列
pop_front :在队列头部出队列
4. 标准容器类 deque list 满足了这些要求。默认情况下,如果没有为 queue 实例化指定容器类,则使用标准容器deque

3. priority_queue的介绍

官方实现priority_queue :本质是一个数组,因为被按照特定顺序排列,也又叫做 “堆”。
1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。(默认建大堆,降序排列)
2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素 ( 优先队列中位于顶部的元素)
3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类 queue 提供一组特 定的成员函数来访问其元素。元素从特定容器的“ 尾部 弹出,其称为优先队列的顶部。
4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭 代器访问,并支持以下操作:
empty() :检测容器是否为空
size() :返回容器中有效元素个数
front() :返回容器中第一个元素的引用
push_back() :在容器尾部插入元素
pop_back() :删除容器尾部元素
5. 标准容器类 vector deque 满足这些需求。默认情况下,如果没有为特定的 priority_queue 类实例化指 定容器类,则使用vector
6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数 make_heap、 push_heap pop_heap 来自动完成此操作。
※注意:
优先级队列默认使用 vector 作为其底层存储数据的容器,在 vector 上又使用了堆算法将 vector 中元素构造成 堆的结构,因此 priority_queue 就是堆,所有需要用到堆的位置,都可以考虑使用 priority_queue 默认情况下 priority_queue 是大堆(会对数组元素进行降序排列)
在上方的官方实现当中有:class Container=deque<T>     class Container=vector<T>
在 C++ 中,一个 Containe 类会使用标准模板库(STL)中的容器类,如deque,来管理元素,来使stack和queue做容器适配器发挥它们的功能。
补充:
上述场景中stack和queue是通过用deque(class Container=deque<T>)当作容器适配器来实现stack和queue的功能;
priority_queue通过用vector( class Container=vector<T>)当作容器适配器来实现priority_queue的功能。
代码示例用class Container=deque<T>实现一个stack
#pragma oncenamespace xcn
{template<class T, class Container = deque<T>>class stack{public:void push(const T& x){_con.push_back(x);}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;};void test_stack(){stack<int> s;//如果不写 默认使用deque<int>进行适配//stack<int, vector<int>> s;//stack<int, list<int>> s;//stack<int, string> s; s.push(1);s.push(2);s.push(3);while (!s.empty()){cout << s.top() << " ";s.pop();}cout << endl;}
}

4.deque的介绍

官方实现deque:兼容 vector和list的功能
deque( 双端队列 ) :是一种双开口的 " 连续 " 空间的数据结构 ,双开口的含义是:可以在头尾两端进行插入和 删除操作,且时间复杂度为O(1) ,与 vector 比较,头插效率高,不需要搬移元素;与 list 比较,空间利用率比较高。
deque 并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际 deque 类似于一个动态的二维 数组 ,其底层结构如下图所示:
+-------+   +-------+   +-------+   +-------+
| Block |-->| Block |-->| Block |-->| Block |
+-------+   +-------+   +-------+   +-------+^           ^           ^           ^|           |           |           ||           |           |           |
+---------------------------------------------+
|        指针数组(Map)                        |
+---------------------------------------------+
  • 每个“Block”表示一个内存块,存储deque的一部分元素。其中每个“Block”用迭代器来维护它的空间:cur、first、last、node。
  • “Map”是一个指向这些内存块的指针数组。

deque就是可以替代vector和list,但也不是完全替代,也有它的缺陷:

(1). deque 与vector比较:
deque 的优势是:头部插入和删除时, 不需要搬移元素,效率特别高 ,而且在 扩容时,也不 需要搬移大量的元素 ,因此其效率是必 vector 高的。
(2).deque与list 比较:
其底层是连续空间(但并不是真正的连续), 空间利用率比较高 ,不需要存储额外字段。
但是, deque 有一个致命缺陷:不适合遍历,因为在遍历时, deque 的迭代器要频繁的去检测其是否移动到 某段小空间的边界,导致效率低下 ,而序列式场景中,可能需要经常遍历,因此 在实际中,需要线性结构 时,大多数情况下优先考虑 vector list deque 的应用并不多,而 目前能看到的一个应用就是, STL将deque 用其作 stack queue 的底层数据结构

5.deque补充说明

(1)vector和list的区别:
vector是一个可动态增长的 数组
优点:可以进行随机访问,很好的支持排序、二分查找、堆算法等等。
缺点:头部或者中间的插入删除效率低(头插头删效率低),并且空间不够了以后增容的代价较大,需要拷贝数据。
list是一个带头双向循环的 链表
优点:任意位置插入删除数据效率高,时间复杂度:0(1)
缺点:不支持随机访问
总结: vector和list是两个相辅相成,互补的容器。
有没有一种数据结构可以解决vector和list的缺点呢?
解决方法:deque容器(见上方)
但是也不是说deque容器完全替代了vector和list容器,deque容器也有缺陷:
  • 大量的频繁的遍历,效率低。
  • 迭代器的遍历相对复杂,效率受到影响。

补充:

容器适配器(stack/queue/ priority_queue)都不支持迭代器遍历,因为他们通常都包含一些特殊性质,如果支持迭代器随便遍历,那他们无法很好的保持他的性质。比如:先进先出,后进先出,这些特有性质。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/410198.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统之家游戏专用版Win10系统:游戏玩家首选!

今天系统之家小编给大家带来最新的Win10游戏专用版&#xff0c;该版本系统是专为游戏玩家打造的操作系统&#xff0c;针对大型游戏做了专业优化&#xff0c;性能更优秀&#xff0c;玩家玩游戏体验感更好&#xff0c;还有出色的兼容性支持&#xff0c;能完美兼容各种类型的游戏&…

【与C++的邂逅】--- 模板初阶

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; 与C的邂逅 本篇博客我们将了解C中泛型编程体现的一大利器 --- 模板&#xff0c;有了模板可以帮我们用户省力。 &#x1f3e0; 泛型编程 如何实现一个通…

Python数据采集与网络爬虫技术实训室解决方案

在大数据与人工智能时代&#xff0c;数据采集与分析已成为企业决策、市场洞察、产品创新等领域不可或缺的一环。而Python&#xff0c;作为一门高效、易学的编程语言&#xff0c;凭借其强大的库支持和广泛的应用场景&#xff0c;在数据采集与网络爬虫领域展现出了非凡的潜力。唯…

聚鼎科技:新人开一家装饰画店铺怎么快速起店

在当下这个看重审美和个性表达的时代&#xff0c;开设一家装饰画店铺无疑是迎合市场的明智选择。对于新人来说&#xff0c;快速且有效地启动一家装饰画店铺并非易事&#xff0c;但通过遵循一些关键步骤&#xff0c;可以大大缩短起步时间并提高成功率。 进行市场调研&#xff0c…

用序列模型(GPT Bert Transformer等)进行图像处理的调研记录

Visual Autoregressive Modeling: Scalable Image Generation via Next-Scale Prediction 北大和字节团队的一篇VLM&#xff0c;在生成任务上&#xff0c;用GPT范式&#xff0c;声称在FID上超过了DIT&#xff0c;SD3和SORA。开源。首先是multi-scale的VQVAE&#xff0c;然后是…

足球联赛|基于SprinBoot+vue的足球联赛管理系统(源码+数据库+文档)

足球联赛管理系统 目录 基于SprinBootvue的足球联赛管理系统 一、前言 二、系统设计 三、系统功能设计 5.1 系统前台功能实现 5.2 后台功能模块实现 5.2.1 管理员模块实现 5.2.2 用户后台模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选…

Linux离线安装fontconfig

Linux离线下载yum包&#xff0c;安装字体库 一、下载安装包 以CentOS Linux release 7.9.2009下载fontconfig的rpm包的为例 http://mirror.centos.org/centos/7/按提示跳转历史库 找到对应版本的centos https://vault.centos.org/7.9.2009/os/x86_64/Packages/在Packages目…

Level3 — PART 4 机器学习算法 — 决策树

目录 引言 信息量 信息熵 案例 ID3 属性选择—信息增益 决策树生成 Python实现ID3 C4.5 属性选择—信息增益率 连续型属性 缺失值 剪枝 CART 分类树属性选择—基尼系数 回归树属性选择—方差 剪枝 Python实现CART CHAID GBRT 决策树对比 模拟题 CDA L…

集团数字化转型方案(十六)

为了全面推进集团的数字化转型&#xff0c;我们将实施一系列战略举措&#xff0c;包括整合最新的人工智能、大数据分析和云计算技术&#xff0c;升级企业资源规划&#xff08;ERP&#xff09;系统&#xff0c;实现业务流程的自动化与优化&#xff1b;同时&#xff0c;建立全方位…

在银河麒麟服务器V10上源码编译安装mysql-5.7.42-linux-glibc2.12-x86_64

在银河麒麟服务器V10上源码编译安装mysql-5.7.42-linux-glibc2.12-x86_64 一、卸载MariaDB&#xff08;如果已安装&#xff09;二、下载MySQL源码包并解压三、安装编译所需的工具和库四、创建MySQL的安装目录及数据库存放目录五、编译安装MySQL六、配置MySQL七、设置环境变量八…

用EA和SysML一步步建模的操作指南(01)

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 对于许多学习SysML和MBSE的同学来说&#xff0c;比较头痛的问题之一是&#xff1a;各种各样的教程里给出的案例&#xff0c;图都是画好了的&#xff01;如何从零开始用建模工具把模型画…

centos7.9系统安装cloudpods并使用ceph存储(二)

1.ceph安装 1.1 环境准备 配置hosts&#xff1a; $ vim /etc/hosts 10.121.x.x node01设置ssh无密码登录&#xff1a; # ssh-keygen -t rsa # ssh-copy-id -i /root/.ssh/id_rsa node01关闭selinux、firewalld # setenforce 0 # sed -i "s#SELINUXenforcing#SELINUXd…

如何使用双重IP代理实现更安全的网络访问

在进行网络爬虫或其他需要隐匿真实IP的操作时&#xff0c;单一的代理IP有时并不能完全满足我们的需求。为了进一步提高安全性和隐私保护&#xff0c;我们可以使用双重IP代理。本文将详细介绍如何使用Java实现双重IP代理&#xff0c;帮助你在网络环境中更加游刃有余。 什么是双重…

安装CUDA以及GPU版本的pytorch

使用pytorch进行深度学习的时候&#xff0c;往往想用GPU进行运算来提高速度。于是搜索便知道了CUDA。 下面给出一个自检的建议&#xff1a; 检查cuda的版本是否适配自己的GPU。 打开NVDIA控制面板&#xff0c;点击左下角“系统信息”&#xff0c;然后就可以看到NVDIA GPU的详…

深入了解搜索引擎蜘蛛:从定义到最新技术应用

撰写一篇关于搜索引擎蜘蛛的详细文章&#xff0c;需涵盖从基础概念到未来趋势的多个方面。以下是根据您提供的大纲撰写的长篇文章&#xff0c;适合用于了解搜索引擎蜘蛛的重要性及其在现代互联网中的作用。 1. 引言 在互联网的浩瀚世界中&#xff0c;搜索引擎就像是庞大的图书…

Python开发工具:VSCode+插件

本文是 Python 系列教程第 3 篇&#xff0c;完整系列请查看 Python 专栏。 Visual Studio Code的安装非常简单&#xff0c;就不放这里增加文章篇幅了。 相比PyCharm&#xff0c;VSCode更加轻量&#xff0c;启动速度快。并且搭配Python插件就能实现和Pycharm一样的代码提示、高…

基于x86 平台opencv的图像采集和seetaface6的人脸跟踪功能

目录 一、概述二、环境要求2.1 硬件环境2.2 软件环境三、开发流程3.1 编写测试3.2 配置资源文件3.3 验证功能一、概述 本文档是针对x86 平台opencv的图像采集和seetaface6的人脸跟踪功能,opencv通过摄像头采集视频图像,将采集的视频图像送给seetaface6的人脸跟踪模块从而实现…

livekit安装脚本详解

livekit安装脚本详解 在私有化部署时&#xff0c;官网是执行了一个脚本。接下来将对这个脚本进行解析。 livekit脚本解析 脚本最终地址是&#xff1a; https://raw.githubusercontent.com/livekit/livekit/master/install-livekit.sh脚本内容解析&#xff1a; # 脚本头部和…

利用机器学习推动 vSOC 检测

我们讨论了汽车 API 如何成为智能移动生态系统的主要攻击媒介之一。与此相关的风险是显而易见的。如果威胁行为者能够大规模远程利用 API,他们将有能力损害品牌或提出赎金请求。当然,Splunk 平台的强大之处在于能够从任何数据大规模创建任何用例。在本博客中,我们将深入研究…

信号与系统——定义与分类(1)

一、信号与系统 信号&#xff1a;信号是信息的表现形式或传送载体&#xff0c;例如电磁波。信号可以用一个函数 yx (t) 来表示。 系统&#xff1a;是指若干相互关联的事物组合而成,具有特定功能的整体。换句话说就是&#xff0c;系统就是对输入信号进行加工和处理&#xff0c…