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

【C++】STL中的容器适配器 stack queue 和 priority_queue 的模拟实现

STL中的容器适配器

  • 一、容器适配器
    • 1、什么是容器适配器
    • 2、STL标准库中的容器适配器
  • 二、stack的模拟实现
    • 1、stack的简单介绍
    • 2、栈的模拟实现
  • 三、queue的模拟实现
    • 1、queue的简单介绍
    • 2、queue的模拟实现
  • 四、priority_queue的模拟实现
    • 1、priority_queue的简单介绍
    • 2、priority_queue的模拟实现

一、容器适配器

1、什么是容器适配器

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

例如我们常见的充电器就是一种适配器,它将我们常用的220V交流电压转化为4,5V (或者其他更高的电压) 的直流电压来给我们的电子设备进行充电。

2、STL标准库中的容器适配器

虽然stackqueue priority_queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配

器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stackqueue默认使用dequepriority_queue默认使用了vector

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

二、stack的模拟实现

1、stack的简单介绍

相关文档
stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,但这些容器类应该支持以下操作:

  • empty:判空操作
  • back:获取尾部元素操作
  • push_back:尾部插入元素操作
  • pop_back:尾部删除元素操作

标准容器vectordequelist均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器,默认情况下使用deque

2、栈的模拟实现

为了栈的通用性,这里我们使用模板来进行模拟栈,关于栈的底层容器这里我们选择vector来进行模拟实现。

template<class T, class Container = vector<T>>
class stack
{
public://栈的插入void push(const T& val){//使用底层容器中尾插函数进行插入,栈只能进行栈顶插入和删除_con.push_back(val);}//栈的删除void pop(){//使用底层容器中尾删函数进行插入,栈只能进行栈顶插入和删除_con.pop_back();}//获取栈顶元素T& top(){//返回底层容器中最后一个数据return _con.back();}//const 版本const T& top() const{return _con.back();}//获取数据个数size_t size() const{//返回底层容器中数据的个数return _con.size();}//判空函数bool empty() const{//对底层容器进行判空return _con.empty();}
private://成员变量是一个容器创建的对象Container _con;
};

三、queue的模拟实现

1、queue的简单介绍

相关文档
queue底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:

  • empty:检测队列是否为空
  • size:返回队列中有效元素的个数
  • front:返回队头元素的引用
  • back:返回队尾元素的引用
  • push_back:在队列尾部入队列
  • pop_front:在队列头部出队列

标准容器类dequelist满足了这些要求。默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque

2、queue的模拟实现

为了queue的通用性,这里我们使用模板来进行模拟queue,关于queue的底层容器这里我们选择list来进行模拟实现。

template<class T, class Container = list<T>>
class queue
{
public://队列的插入void push(const T& val){//使用底层容器中尾插函数进行插入,队列只能进行队尾插入_com.push_back(val);}//队列的删除void pop(){//使用底层容器中头删函数进行删除,队列只能进行队头删除_com.pop_front();}//获取队头数据T& front(){//返回底层容器中第一个数据return _com.front();}//const版本const T& front() const{return _com.front();}//获取队尾数据T& back(){//返回底层容器中最后一个数据return _com.back();}//const版本const T& back() const{return _com.back();}//获取数据个数size_t size() const{//返回底层容器中数据的个数return _com.size();}//判空函数bool empty() const{//对底层容器进行判空return _com.empty();}
private://成员变量是一个容器创建的对象Container _com;
};

四、priority_queue的模拟实现

1、priority_queue的简单介绍

相关文档
优先队列是一种容器适配器,它其实就是我们数据结构中的,默认情况下priority_queue是大堆。

priority_queue底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:

  • empty:检测容器是否为空
  • size:返回容器中有效元素个数
  • front:返回容器中第一个元素的引用
  • push_back:在容器尾部插入元素
  • pop_back:删除容器尾部元素

标准容器类vectordeque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指定容器类,则使用vector

2、priority_queue的模拟实现

与前面的栈与队列一样priority_queue前两个模板参数都类似,但是priority_queue要有第三个模板参数,这个参数表示按照什么方式进行比较,即建立大堆还是小堆。

//第三个参数是比较方式,需要传递一个仿函数来确定比较方式,默认传递的是less<T>,表示建大堆
template<class T, class Container = vector<T>, class Comper = less<T>>
class priority_queue
{
public://获取堆顶数据const T& top() const{//返回底层容器的第一个数据return _con.front();}//获取数据个数size_t size() const{//返回底层容器的数据个数return _con.size();}//判空函数bool empty() const{//判断底层容器是否为空return _con.empty();}//堆的插入void push(const T& val){//从尾部插入_con.push_back(val);int child = _con.size() - 1;//向上调整重新建堆AdjustUp(child);}//堆的删除void pop(){//检查堆是否为空assert(!_con.empty());//交换堆顶与最后一个数据swap(_con.front(), _con.back());//删除最后一个数据_con.pop_back();//从堆顶进行向下调整,重新建堆AdjustDown(0);}private://向上调整算法void AdjustUp(int child){Comper com;int parent = (child - 1) / 2;while (child > 0){//这里使用了仿函数来判断建立什么堆//比较的位置(_con[parent], _con[child])是不能换的!!!if (com(_con[parent], _con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}//向下调整算法void AdjustDown(int parent){Comper com;//默认左孩子更符合建堆的要求int child = parent *2 + 1;while (child < _con.size()){if (child + 1 < _con.size() && Comper()(_con[child], _con[child + 1])){++child;}if (com(_con[parent], _con[child])){swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}//成员变量是一个容器创建的对象Container _con;
};

相关文章:

【C++】STL中的容器适配器 stack queue 和 priority_queue 的模拟实现

STL中的容器适配器 一、容器适配器1、什么是容器适配器2、STL标准库中的容器适配器 二、stack的模拟实现1、stack的简单介绍2、栈的模拟实现 三、queue的模拟实现1、queue的简单介绍2、queue的模拟实现 四、priority_queue的模拟实现1、priority_queue的简单介绍2、priority_qu…...

MongoDB 聚合管道中使用算术表达式运算符

算术表达式运算符主要用于实现数字之间的算术运算&#xff0c;主要包含了对加、减、乘、除、余数、截取、舍入等算术操作。 下面我们进行详细介绍&#xff1a; 一、准备数据 初始化商品数据 db.goods.insertMany([{ "_id": 1, name: "薯片", size: &q…...

代码随想录算法训练营第四十三天-动态规划5|1049. 最后一块石头的重量 II , 494. 目标和 , 474.一和零

最后一块石头重量转化为将一个集合分隔成两个集合&#xff0c;两个集合之间的差值最小&#xff0c;就是最后剩下最小的石头重量。这里可以求集合的一个平均值&#xff0c;如果正好等于平均值&#xff0c;说明可以抵消&#xff0c;这时候重量为0&#xff0c;如果不行&#xff0c…...

《淘宝网店》:计算总收益

目录 一、题目 二、思路 1、当两个年份不一样的时候 &#xff08;1&#xff09;from年剩余之后的收益 &#xff08;2&#xff09;中间年份的全部收益 &#xff08;3&#xff09;to年有的收益 2、同一个年份 三、代码 详细注释版本&#xff1a; 简化注释版本&#xff…...

2023年03月青少年软件编程C语言一级真题答案——持续更新.....

1.字符长方形 给定一个字符,用它构造一个长为4个字符,宽为3个字符的长方形,可以参考样例输出。 时间限制:1000 内存限制:65536 输入 输入只有一行, 包含一个字符。 输出 该字符构成的长方形,长4个字符,宽3个字符。 样例输入 * 样例输出 **** **** ****#include<bi…...

家用洗地机好用吗?好用的洗地机分享

洗地机是一种高效、节能、环保的清洁设备&#xff0c;广泛应用于各种场所的地面清洁工作。它不仅可以快速清洁地面&#xff0c;还可以有效去除污渍、油渍等难以清洁的污染物&#xff0c;让地面恢复光洁如新的状态。同时&#xff0c;洗地机还可以减少清洁人员的劳动强度&#xf…...

《分解因数》:质因数分解

目录 一、题目&#xff1a; 二、思路&#xff1a; 三、代码&#xff1a; 一、题目&#xff1a; 分解因数 《分解因数》题目链接 所谓因子分解&#xff0c;就是把给定的正整数a&#xff0c;分解成若干个素数的乘积&#xff0c;即 a a1 a2 a3 ... an,并且 1 < a1…...

(排序10)归并排序的外排序应用(文件排序)

TIPS 在一些文件操作函数当中&#xff0c;fputc与fgetc这两个函数都是针对字符的&#xff0c;如果说你需要往文件里面去放入整形啊等等&#xff0c;不是字符的类型&#xff0c;这时候就用fprintf&#xff0c;fscanf在参数里面数据类型控制一下就可以。但是话说回来&#xff0c…...

浅谈根号分治与分块

文章目录 1. 根号分治哈希冲突 2. 线性分块引入教主的魔法[CQOI2011] 动态逆序对[国家集训队] 排队[HNOI2010] 弹飞绵羊蒲公英 1. 根号分治 哈希冲突 题目1 n n n 个数&#xff0c; m m m 次操作。操作 1 为修改某一个数的值&#xff0c;操作 2 为查询所有满足下标模 x x x …...

(OpenAI)ChatGPT注册登录常见问题错误代码及其解决方法

在使用 ChatGPT 的时候我们可能会碰到一些错误的代码&#xff0c;本文统一来介绍一下每一种错误以及解决方法。 错误代码1. 不能在当前国家使用 出现场景&#xff1a;一般在注册或登录的时候会出现。 原因&#xff1a;主要是ChatGPT检测到当前访问所在的地区不允许访问导致。 …...

MySQL主从复制、读写分离(MayCat2)实现数据同步

文章目录 1.MySQL主从复制原理。2.实现MySQL主从复制&#xff08;一主两从&#xff09;。3.基于MySQL一主两从配置&#xff0c;完成MySQL读写分离配置。&#xff08;MyCat2&#xff09; 1.MySQL主从复制原理。 MySQL主从复制是一个异步的复制过程&#xff0c;底层是基于Mysql数…...

Linux 云服务器好用吗?(解读Linux云服务器的特点优势)

​  如今&#xff0c;云计算越来越受欢迎&#xff0c;许多公司正在将业务转移到那里。企业向云过渡的主要原因是它提供的众多服务&#xff0c;包括安全和充足的存储、数据库、服务器和其他关键元素。 作为相对前|沿的技术之一&#xff0c;云建立在虚拟服务器上。Linux 服务器…...

研读Rust圣经解析——Rust learn-8(match,if-let简洁控制流,包管理)

研读Rust圣经解析——Rust learn-8&#xff08;match,if-let简洁控制流&#xff0c;包管理&#xff09; matchother和占位符_区别 easy matchenum matchno valuematch inner Option matchmore better way if-let整洁控制包管理模块(mod)拆分声明modpub公开use展开引用拆解模块结…...

G8期刊《全体育》期刊简介及投稿要求

G8期刊《全体育》期刊简介及投稿要求 《全体育》是由湖南体育产业集团有限公司主管、体坛传媒集团股份有限公司主办、中教体育 出版发行的体育综合性期刊。 主管&#xff1a;湖南体育产业集团有限公司 主办&#xff1a;体坛传媒集团股份有限公司 国内刊号&#xff1a;CN4…...

数据结构和算法学习记录——层序遍历(层次遍历)、二叉树遍历的应用(输出二叉树中的叶节点、求二叉树的高度、二元运算表达式树及其遍历、由两种遍历序列确定二叉树)

目录 层序遍历 思路图解 代码实现 二叉树遍历的应用 输出二叉树中的叶节点 代码实现 求二叉树的高度 思路图解 代码实现 二元运算表达式树及其遍历 由两种遍历序列确定二叉树 层序遍历 层序遍历可以通过一个队列来实现&#xff0c;其基本过程为&#xff1a; 先根…...

【Neo4j数据库】图数据库_Neo4j增加节点(关系)、查询、删除数据库等操作解析(Cypher语句)

【Neo4j数据库】图数据库_Neo4j增加节点&#xff08;关系&#xff09;、查询、删除操作解析&#xff08;Cypher语句&#xff09; 文章目录 【Neo4j数据库】图数据库_Neo4j增加节点&#xff08;关系&#xff09;、查询、删除操作解析&#xff08;Cypher语句&#xff09;1. 介绍2…...

Linux移动文件和文件夹(目录)命令

命令mv 英文move 翻译移动 mv命令可以移动文件或文件夹&#xff08;目录&#xff09;&#xff0c;也可以重命令&#xff08;覆盖&#xff09;文件。 1. 移动文件/重命名 单纯地移动某一个文件直接使用&#xff1a; mv <源文件名称/地址> <新文件名称/地址>这个方法…...

Pandas的应用-5

Pandas是一个强大的数据处理库&#xff0c;它提供了高性能、易于使用的数据结构和数据分析工具。本文将介绍Pandas常用的数据结构和常用的数据分析技术&#xff0c;包括DataFrame的应用、窗口计算、相关性判定、Index的应用、范围索引、分类索引、多级索引以及日期时间索引。 …...

java继承类怎么写

继承类是通过把父类的方法和属性继承到一个类中&#xff0c;而子类的方法和属性是子类自己定义的。 Java中有一个很重要的概念叫做继承&#xff0c;这也是 Java语言的精髓所在。Java语言提供了一种机制&#xff0c;叫做派生类。在 Java中&#xff0c;如果没有实现了某个派生类方…...

面向对象程序设计

OOP 【面向对象程序设计】&#xff08;OOP&#xff09;与【面向过程程序设计】在思维方式上存在着很大的差别。【面向过程程序设计】中&#xff0c;算法是第一位的&#xff0c;数据结构是第二位的&#xff0c;这就明确地表述了程序员的工作方式。首先要确定如何操作数据&#…...

04_运算符表达式与类型转换

运算符、表达式与类型转换 一、本篇文章要解决什么问题 你已经知道怎么定义变量、怎么输入输出了。但程序光有数据不行&#xff0c;还得对数据做运算——加减乘除、比较大小、逻辑判断。 这篇文章就帮你搞定三件事&#xff1a; C 语言里有哪些运算符&#xff1f;算术的、赋值的…...

从订阅到命令面板:全面理解 SAP Business Application Studio 中的 SAP Fiori 开发入口

在很多 SAP Fiori 项目里,团队把精力都放在 SAPUI5、OData、Fiori elements、注解模型和部署流程上,却常常低估了开发环境本身对效率的影响。等到项目进入多人协作、跨系统联调、权限分配和模板生成阶段,大家才会发现,开发工具并不只是一个写代码的地方,它实际上决定了团队…...

别再只用if-else了!Matlab里switch/case的5个高效用法与避坑指南

别再只用if-else了&#xff01;Matlab里switch/case的5个高效用法与避坑指南 在Matlab编程中&#xff0c;if-else语句几乎是每个开发者最先掌握的控制结构之一。但当你开始处理更复杂的条件逻辑时&#xff0c;一长串的if-elseif-else语句不仅让代码变得难以阅读&#xff0c;还可…...

VSCode里PlatformIO插件抽风?手把手教你彻底卸载重装PIO(解决创建工程失败)

VSCode PlatformIO插件异常终极解决手册&#xff1a;从崩溃到重生的全流程指南 当你在VSCode中满怀期待地点击"New Project"按钮&#xff0c;却看到那个刺眼的红色错误提示时&#xff0c;那种挫败感每个开发者都懂。PlatformIO作为物联网开发的瑞士军刀&#xff0c;一…...

LangGraph入门:构建有状态的AI Agent工作流

LangGraph 入门&#xff1a;用状态图构建 Agent手写 ReAct 循环容易写出 bug。LangGraph 用「状态图」的方式定义 Agent&#xff0c;把每一步定义为一个节点&#xff0c;跳转逻辑定义为边——清晰、可测试、可扩展。一、为什么需要 LangGraph 手写 Agent 循环的痛点&#xff1a…...

【LabVIEW】驱动文件部署策略全解析:项目嵌入与系统集成的权衡与实践

1. LabVIEW驱动文件部署的核心挑战 第一次用LabVIEW控制仪器设备时&#xff0c;我盯着官方提供的驱动压缩包发呆了半小时——该把这些文件扔到哪个文件夹&#xff1f;这个问题看似简单&#xff0c;却直接关系到后续开发的便利性和项目可移植性。经过多个项目的实战验证&#xf…...

从‘亮灯’到‘定位’:一个真实商用车J1939故障排查全记录(含DM1多包传输解析)

从‘亮灯’到‘定位’&#xff1a;一个真实商用车J1939故障排查全记录&#xff08;含DM1多包传输解析&#xff09; 1. 故障现象与初步诊断 那是一个普通的周二早晨&#xff0c;维修车间接到一辆6x4牵引车的报修单——仪表盘上的MIL&#xff08;故障指示灯&#xff09;持续点亮。…...

CircuitFusion:多模态融合技术在芯片设计PPA预测中的应用

1. CircuitFusion&#xff1a;硬件设计领域的多模态融合革命在芯片设计领域&#xff0c;RTL&#xff08;寄存器传输级&#xff09;到GDSII&#xff08;物理版图&#xff09;的转换过程一直面临着"预测鸿沟"的挑战。传统EDA工具通常在完成逻辑综合后才能准确评估时序、…...

OctoBase源码解析:深入理解Rust实现的本地优先数据库引擎 [特殊字符]

OctoBase源码解析&#xff1a;深入理解Rust实现的本地优先数据库引擎 &#x1f419; 【免费下载链接】OctoBase &#x1f419; OctoBase is the open-source database behind AFFiNE, local-first, yet collaborative. A light-weight, scalable, data engine written in Rust.…...

Qt开发避坑|MQTT客户端频繁下线?竟是setClientId用错了!

做Qt物联网开发的小伙伴&#xff0c;大概率都遇到过这样的坑&#xff1a;本地调试时&#xff0c;MQTT客户端连接正常、消息收发流畅&#xff1b;可当另一个设备&#xff08;或另一个调试窗口&#xff09;启动后&#xff0c;前一个客户端突然被强制下线&#xff0c;日志里没明确…...