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

【C++进阶(六)】STL大法--栈和队列深度剖析优先级队列适配器原理

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C++从入门到精通⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习C++
  🔝🔝


在这里插入图片描述

栈和队列

  • 1. 前言
  • 2. 栈和队列的接口函数熟悉
  • 3. 适配器介绍
  • 4. 栈和队列的模拟实现
  • 5. deque的简单介绍
  • 6. 优先级队列深度剖析
  • 7. 优先级队列的模拟实现
  • 8. 总结以及拓展

1. 前言

和C语言学习期间的学习顺序一样
顺序表,链表过了就是栈和队列
但是栈和队列非常特殊,它的内部结构
并不是靠自己实现的,而是一种适配器模式

本章重点:

本篇文章着重讲解适配器原理
和栈,队列的接口函数熟悉以及模拟实现
适配器里有一个特殊容器:deque
最后讲解优先级队列相关知识和实现

在这里插入图片描述

在这里插入图片描述


2. 栈和队列的接口函数熟悉

栈的接口函数熟悉:

在这里插入图片描述

由于栈结构只能支持栈顶插入,栈顶pop
所以它的接口很少,这里就不多介绍了!

队列的接口函数熟悉:

在这里插入图片描述

队列只比栈多了一个接口:back
队列的front相当于栈的top

在了解了接口函数后,可以尝试做几个题巩固

  1. 最小栈
  2. 栈的压入,弹出序列
  3. 逆波兰表达式求值
  4. 用两个栈实现队列

3. 适配器介绍

先看栈和队列的类模板:

在这里插入图片描述

我们发现第二个模板参数是:Container
并且它还有缺省值为 deque<T>

这里就直接引出一个概念: 适配器

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

一个比较经典的例子就是插头的适配器:

在这里插入图片描述

那么在数据结构栈中,这种适配器是什么呢?

很显然,在C语言阶段实现栈时,我们
使用的底层是顺序表来实现,也就是
把顺序表做了一层封装和限制,让它
的功能变得和栈一样,C++这里也是一样!

我们在实现栈时不用再去写一个顺序表
而是直接调用库中的vector!


4. 栈和队列的模拟实现

栈的模拟实现要复用其他数据结构
所以在定义模板时要定义两个!

template<class T, class Container = deque<T>>
class Stack
{//......
private:Container _con;
}

我们和库中的缺省值保持一致,使用deque
这个容器我们后面会有所解释!

这样使用栈非常的方便!因为此时的栈
就像"富二代"一样,不用写构造和析构函数
因为默认生成的构造或析构会去调用
内嵌类型的构造或析构帮助我们完成任务!

在此之后,只需要实现一些接口函数即可!

void push(const T& val)
{_con.push_back(val);
}void pop()
{_con.pop_back();
}T& top()//可读可写
{return _con.back();
}const T& top() const
{return _con.back();
}bool empty() const
{return _con.empty();
}size_t size() const
{return _con.size();
}

注:函数中的push_back或back等
函数接口是调用适配器中的!如vector中的

栈的结构实现完成,队列就交给你们了!


5. deque的简单介绍

deque也是一个STL库中的容器
先来看看它的介绍:

在这里插入图片描述

deque又被称为双端队列是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素,与list比较,空间利用率比较高

在这里插入图片描述

接下来看看它的接口函数:

在这里插入图片描述

deque既有头插头删也有尾插尾删
这是意料之中,它也支持方括号[]
其实对于deque的了解到这里就差不多了
下面的内容属于拓展了解,有兴趣的可以看看

deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组,其底层结构如下图所示:

在这里插入图片描述
deque扩容是直接另外开辟一份空间
再让中控数组指向新开辟的空间
再将原先空间的内容拷贝至新空间

注意它有一个中控数组的概念!


6. 优先级队列深度剖析

优先级队列的英文是: priority_queue
它也是一个容量适配器,文档的大致翻译:

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

优先级队列默认是大堆!

在这里插入图片描述

并且它的底层适配器默认是vector

优先级队列默认有三个类模板,然而第三个
模板就是决定此优先级队列是大堆还是小堆
它叫仿函数,我们先不管它,下一篇文章回讲解
我们需要了解的是,默认的less是大堆
我们显示传参greater时是小堆!

优先级队列的接口函数熟悉:

在这里插入图片描述

注:如果你想使用小堆,就要将前两个
模板参数实例化后才能实例化第三个
当less变成greater时,就是小堆


7. 优先级队列的模拟实现

在学习仿函数之前,先实现无仿函数版本:

基本结构和框架:

template<class T, class Container = vector<T>>
class Priority_queue
{
public://成员函数
private:Container _con;//此容器可能是vector可能是deque
};

由于优先级队列是"富二代",所以
构造,析构和拷贝构造都可以忽略不写

优先级队列的插入和删除操作:

由于优先级队列实际上就是个堆
所以在插入,删除之后.都需要做一件事
那就是向上调整或向下调整!所以插入和
删除的关键其实就在于向上/下调整!

向上调整:

void AdjustUp(int* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}

向下调整:

void AdjustDown(int* a, int n, int parent)
{int child = parent * 2 + 1;while (child < n){if (a[child+1] < a[child] && child + 1 < n){child++;}if (a[child] < a[parent]){swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}

这两个操作在学习堆时就已经实现过了,老朋友了

详情可看: 堆以及topk问题

优先级队列的插入和删除

void push(const T& val)//堆的插入
{_con.push_back(val);adjust_up(_con.size() - 1);
}void pop()//堆的删除
{std::swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjust_down(0);
}

插入和删除可谓是和堆的做法一模一样
其他的函数接口也是如此,这里就不多解读
我把优先级队列模拟实现的所有代码分享出来:

优先级队列模拟实现全部代码


8. 总结以及拓展

其实我们可以感受到,有了前面STL
容器的学习,现在学习栈和队列要轻松许多
不仅是模拟实现上可以复用以前的容器
连使用方法和函数接口都和之前一样
这就是C++STL的魅力所在!

拓展阅读:
对于deque我们还有很多未知的地方
比如它的扩容是怎样完成的?是否是缩容?
deque是如何支持随机访问的?deque的缺陷?

有兴趣的老铁可以阅读下面这篇文章:

deque深度剖析


🔎 下期预告:模板进阶以及仿函数 🔍

相关文章:

【C++进阶(六)】STL大法--栈和队列深度剖析优先级队列适配器原理

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; 栈和队列 1. 前言2. 栈和队列的接口函数熟悉3. …...

linux opensuse使用mtk烧录工具flashtool

环境 linux发行版&#xff1a;opensuse leap 15.5 工具&#xff1a;SP_Flash_Tool_Selector_exe_Linux_v1.2316.00.100.rar 或其他版本 目标&#xff1a;mtk设备 下载链接 https://download.csdn.net/download/zmlovelx/88382784 或网络搜索。 使用 opensuse可直接解压后使…...

Visio如何对文本打下标、上标,以及插入公式编辑器等问题(已解决)

解决这个问题的本质问题&#xff0c;就是在Visio中插入公式编辑器&#xff08;这不是visio的常用命令&#xff0c;需要添加&#xff09;。 打开Visio--》文件--选项 点击选项&#xff0c;弹出对话框。在自定义功能区中&#xff0c;点击 常用命令&#xff0c;在下拉选项中&#…...

快速将iPhone大量照片快速传输到电脑的办法!

很多使用iPhone 的朋友要将照片传到电脑时&#xff0c;第一时间都只想到用iTunes 或iCloud&#xff0c;但这2个工具真的都非常难用&#xff0c;今天小编分享牛学长苹果数据管理工具的照片传输功能&#xff0c;他可以快速的将iPhone照片传输到电脑上&#xff0c;并且支持最新的i…...

TCP/IP协议簇包含的协议

应用层&#xff08;Application Layer&#xff09;&#xff1a; HTTP&#xff08;Hypertext Transfer Protocol&#xff09;&#xff1a;用于Web浏览器和Web服务器之间的通信。HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;&#xff1a;安全的HTTP版本&…...

天地图绘制区域图层

背景&#xff1a; 业务方要求将 原效果图 参考效果图 最终实现效果 变更点&#xff1a; 1.将原有的高德地图改为天地图 2.呈现形式修改&#xff1a;加两层遮罩&#xff1a;半透明遮罩层mask区域覆盖物mask 实现过程&#xff1a; 1.更换地图引入源 <link rel"style…...

git权限不够:Ask a project Owner or Maintainer to create a default branch

新仓库还未创建任何分支时&#xff0c;Developer角色时首次提交代码&#xff0c;抛如下异常 remote: GitLab: remote: A default branch (e.g. master) does not yet exist for galaxy/apache-jspf-project remote: Ask a project Owner or Maintainer to cre…...

AI在材料科学中的应用

7 AI在材料科学中的应用 在这一部分&#xff0c;我们将讨论AI技术在材料科学中的应用。首先&#xff0c;我们将介绍晶体材料的概述&#xff0c;并详细定义晶体材料的物理对称性&#xff0c;具体在第7.1节中讨论。接下来&#xff0c;我们将在第7.2节和第7.3节中讨论两个常见且基…...

VSCode快速设置heder和main函数

快速设置header: 点击左侧的齿轮&#xff0c;选择User Snippets&#xff1a; 在出现的选择框中输入python&#xff0c;选择python.json 在最外层的{ }内部添加以下内容 "HEADER": {"prefix": "header","body": ["# -*- encoding:…...

JimuReport积木报表 v1.6.2 版本正式发布—开源免费的低代码报表

项目介绍 一款免费的数据可视化报表&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于excel操作风格&#xff0c;通过拖拽完成报…...

sqlsession对象为什么不能被共享?

因为它是一个非线程安全的对象。每个SQLSession对象都维护了一个独立的数据库连接&#xff0c;以及与该连接相关的事务和缓存。如果多个线程共享同一个SQLSession对象&#xff0c;可能会导致数据混乱、事务冲突等问题。另外&#xff0c;SQLSession对象还包含了一级缓存&#xf…...

MySQL MMM高可用架构

MySQL MMM高可用架构一、MMM概述1、MMM简介2、MMM高可用架构3、MMM故障切换流程 二、MMM高可用双主双从架构部署1、配置主主复制&#xff08;master&#xff09;&#xff0c;主从复制&#xff08;slave&#xff09;1&#xff09;修改 Master1的MySQL配置文件2&#xff09;把配置…...

Spring Boot中配置文件介绍及其使用教程

目录 一、配置文件介绍 二、配置简单数据 三、配置对象数据 四、配置集合数据 五、读取配置文件数据 六、占位符的使用 一、配置文件介绍 SpringBoot项目中&#xff0c;大部分配置都有默认值&#xff0c;但如果想替换默认配置的话&#xff0c;就可以使用application.prop…...

Hobby脚本自动化工具

Hobby脚本自动化工具 功能简介&#xff1a;可以按照指定编排的配置文件&#xff0c;按顺序执行并监听 使用场景&#xff1a;可以用在前期信息收集的步骤上&#xff0c;将一些常见的脚本进行归纳&#xff0c;并编写成配置文档进行自动化处理 优点&#xff1a;可以扩展性强&am…...

Matlab随机数的产生

1、常见分布随机数的产生 1.1 二项分布 在贝努力试验中&#xff0c;某事件A发生的概率为p&#xff0c;重复该实验n次&#xff0c;X表示这n次实验中A发生的次数&#xff0c;则随机变量X服从的概率分布律&#xff08;概率密度&#xff09;为 记为 binopdf(x,n,p) p…...

计算机网络 第四章:网络层

一.网络层概述 1.1分组转发和路由选择 网络层的主要任务就是将分组从源主机经过多个网络和多段链路传输到目的主机&#xff0c;可以将该任务划分为分组转发和路由选择两种重要的功能。 如图所示&#xff1a;这些异构型网络如果只是需要各自内部通信&#xff0c;那它们只需要实…...

分享一个docker无法启动的小问题

准备看看docker服务怎么样 [rootlocalhost ~]# docker ps Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? 这一看就是docker的进程崩了&#xff0c;我们启动下进程 [rootlocalhost ~]# systemctl start docker Faile…...

Linux 安全 - Capabilities机制

文章目录 前言一、简介二、Capabilities list2.1 POSIX-draft defined capabilities2.2 Linux-specific capabilities 三、 Past and current implementation四、Thread capability sets五、File capabilities六、Transformation of capabilities during execve()七、Capabilit…...

分布式搜索引擎es-3

文章目录 数据聚合聚合的种类RestAPI实现聚合 数据聚合 什么是聚合&#xff1f; 聚合可以让我们极其方便的实现对数据的统计、分析、运算。例如&#xff1a; 什么品牌的手机最受欢迎&#xff1f;这些手机的平均价格、最高价格、最低价格&#xff1f;这些手机每月的销售情况如…...

Matlab坐标轴标签中文设置宋体

对y坐标输出中文宋体 新罗马字符 x[1,2,3,4,5,6,7]; plot(x) ylabel(\fontname{宋体}\fontsize{20}长度\fontname{Times New Roman}\fontsize{10} (μm))可以灵活设置字体和大小,其图片如下图所示 也可以对全图的文字设置同一个字体 set(gca,FontSize,9,Fontname, Times New…...

从零开始理解Transformer的计算复杂度:自注意力与前馈网络的详细对比

从零开始理解Transformer的计算复杂度&#xff1a;自注意力与前馈网络的详细对比 在人工智能领域&#xff0c;Transformer架构已经成为自然语言处理任务的事实标准。但对于初学者来说&#xff0c;理解其内部工作机制&#xff0c;特别是计算复杂度这一关键概念&#xff0c;往往充…...

ComfyUI实战:如何加载基于Flux.1微调的LoRA模型并优化推理流程

最近在项目里用 ComfyUI 部署基于 Flux.1 微调的 LoRA 模型&#xff0c;踩了不少坑。从模型加载失败到推理时显存爆炸&#xff0c;问题层出不穷。经过一番折腾&#xff0c;总算梳理出一套比较稳定的流程&#xff0c;这里把实战经验记录下来&#xff0c;希望能帮到有同样需求的同…...

新手零门槛入门:用快马生成你的第一个jiyutrainer式Python练习脚本

作为一个刚接触Python的新手&#xff0c;想要练习编程却常常被各种环境配置和工具安装搞得晕头转向。最近我发现了一个特别适合新手入门的方法——使用InsCode(快马)平台来生成自己的第一个Python练习脚本。下面我就来分享一下这个零门槛的入门体验。 为什么选择jiyutrainer式练…...

League Akari:英雄联盟玩家的终极智能辅助工具实战指南

League Akari&#xff1a;英雄联盟玩家的终极智能辅助工具实战指南 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 你是否厌倦了在…...

游戏原画效率提升50%:Pixel Fashion Atelier在角色装备概念图批量生成中的应用

游戏原画效率提升50%&#xff1a;Pixel Fashion Atelier在角色装备概念图批量生成中的应用 1. 传统游戏原画设计的痛点 游戏开发过程中&#xff0c;角色装备设计往往是最耗时的环节之一。传统工作流程中&#xff0c;美术团队需要&#xff1a; 手工绘制数十种装备变体反复修改…...

软电话通话30秒自动挂断?一文讲透FreeSWITCH通话超时问题

当你满怀期待地搭建好FreeSWITCH&#xff0c;用两个软电话成功呼叫&#xff0c;却发现通话总是在30秒左右莫名其妙地中断——别急&#xff0c;这是SIP新手最常遇到的“经典Bug”。本文将为你抽丝剥茧&#xff0c;彻底解决这个问题&#xff0c;并附带其他可能引发通话异常中断的…...

深入解析DW_I2C驱动中的中断处理机制:从FIFO到数据传输实战

深入解析DW_I2C驱动中的中断处理机制&#xff1a;从FIFO到数据传输实战 在嵌入式Linux开发中&#xff0c;I2C总线作为连接各类传感器的关键通道&#xff0c;其驱动性能直接影响系统响应速度和稳定性。DW_I2C&#xff08;DesignWare I2C&#xff09;作为业界广泛采用的IP核&…...

5个创新方法:基于开源工具的内容访问优化方案

5个创新方法&#xff1a;基于开源工具的内容访问优化方案 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 在信息爆炸的数字时代&#xff0c;合法访问优质内容成为信息获取的关键挑战。…...

HackTricks数字取证方法论:内存转储分析与恶意软件检测完全指南

HackTricks数字取证方法论&#xff1a;内存转储分析与恶意软件检测完全指南 【免费下载链接】hacktricks Welcome to the page where you will find each trick/technique/whatever I have learnt in CTFs, real life apps, and reading researches and news. 项目地址: http…...

OpenClaw隐私保护方案:ollama-QwQ-32B本地化数据处理流程

OpenClaw隐私保护方案&#xff1a;ollama-QwQ-32B本地化数据处理流程 1. 为什么需要本地化隐私保护方案 去年我在处理一份涉及客户隐私的市场分析报告时&#xff0c;遇到了一个棘手问题&#xff1a;当使用云端AI服务进行数据清洗和分析时&#xff0c;不得不将包含敏感字段的原…...