C++的stack和queue+优先队列

文章目录

  • 什么是容器适配器
  • 底层逻辑
  • 为什么选择deque作为stack和queue的底层默认容器
  • 优先队列
  • 优先队列的模拟实现
  • stack和queue的模拟实现

什么是容器适配器

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

底层逻辑

stack和queue都是容器适配器,底层都是通过去适配双端队列deque去实现的,STL中没有把stack和queue划分在容器中,而是放在容器适配器,stack和queue默认使用deque.
在这里插入图片描述
在这里插入图片描述
那可不可以用vector去适配呢?
这也是可以的,只要是他们的所有接口,在这个容器中包含就可以进行适配,那么为什么底层默认会选择使用deque去进行适配呢?
deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。
deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组。
与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。
与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。但是,deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到
某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作为stack和queue的底层数据结构

为什么选择deque作为stack和queue的底层默认容器

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

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

优先队列

优先队列本质上就是topk问题,那么优先队列是怎么实现的呢?
优先队列的底层物理结构是数组,其中模板参数Compare是控制优先队列是大堆还是小堆,
优先队列默认是大堆–缺省参数就是less,如果要给大堆就是greater
这两个模板参数的底层实现:

//仿函数/函数对象
//重载了括号,让类可以向函数一样被调用
template<class T>
class Less
{
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;}
};

优先队列的模拟实现

//优先队列,其实就是topk问题,底层结构就是堆,所以我们用数组---vector来存取数据template<class T, class Container = vector<T>, class Compare = less<T>>//默认是大堆,less对应的就是大堆//greater<T>对应的是小堆 通过传Compare来控制大堆还是小堆,默认不传是大堆//仿函数控制实现大小堆class priority_queue{private:void AdjustDown(size_t parent){Compare com;size_t chidren = parent * 2 + 1;while (chidren < _con.size()){if (chidren + 1 < _con.size() && com( _con[chidren], _con[chidren + 1])){chidren += 1;}//if (_con[parent] < _con[chidren])if (com(_con[parent], _con[chidren])){swap(_con[parent], _con[chidren]);parent = chidren;chidren = parent * 2 + 1;}else{break;}}}void AdjustUp(int chidren){Compare com;int parent = (chidren - 1) / 2;while (parent >= 0){if (com(_con[parent], _con[chidren])){swap(_con[chidren], _con[parent]);chidren = parent;parent = (chidren - 1) / 2;}else{break;}}}public:priority_queue(){}template<class InputInterator>priority_queue(InputInterator first, InputInterator last){//插入数据while (first != last){_con.push_back(*first);++first;}//建堆//从最后一个非叶子节点开始建堆-----关键for (int i = (_con.size()-1-1) / 2; i >= 0; i--){AdjustDown(i);}}void pop()//删除的是第一个元素{swap(_con[0], _con[_con.size() - 1]);_con.pop_back();AdjustDown(0);}void push(const T& x){//_con[_con.size()] = x;_con.push_back(x);AdjustUp(_con.size() - 1);}T& top(){return _con[0];}bool empty(){return _con.empty();}size_t size(){return _con.size();}private:Container _con;};

stack和queue的模拟实现

#pragma once//适配器模拟实现
namespace sw
{	//数组栈与链式栈之间秒切换---------适配器template<class T, class Container = deque<T>>//模板参数不仅可以是int,double等内置类型也可以是容器,同时也可以给缺省值class stack{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}T& top(){return _con.back();//取最后一个元素,}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};void test_stack(){cout << "stack" << endl;stack<int, vector<int>> st1;st1.push(1);st1.push(2);st1.push(3);st1.push(4);while (!st1.empty()){cout << st1.top() << " ";st1.pop();}cout << endl;stack<int, list<int>> st2;st2.push(1);st2.push(2);st2.push(3);st2.push(4);while (!st2.empty()){cout << st2.top() << " ";st2.pop();}cout << endl;stack<int> st3;st3.push(1);st3.push(2);st3.push(3);st3.push(4);while (!st3.empty()){cout << st3.top() << " ";st3.pop();}cout << endl;}
}
#pragma oncenamespace sw
{//适配器template<class T, class Container = deque<T>>//模板参数不仅可以是int,double等内置类型也可以是容器,同时也可以给缺省值class queue{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_front();}T& front(){return _con.front();}T& back(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};void test_queue(){cout << "queue" << endl;queue<int, deque<int>> q1;q1.push(1);q1.push(2);q1.push(3);q1.push(4);while (!q1.empty()){cout << q1.front() << " ";q1.pop();}cout << endl;queue<int, list<int>> q2;q2.push(1);q2.push(2);q2.push(3);q2.push(4);while (!q2.empty()){cout << q2.front() << " ";q2.pop();}cout << endl;}
}

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

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

相关文章

R语言实现计算净重新分类指数(NRI)和综合判别改善指数(IDI)

两个模型比较&#xff0c;与第一个模型相比&#xff0c;NRI&#xff08;重新分对的 - 重新分错的&#xff09;/总人数。IDI&#xff08;新模型患者平均预测概率-旧模型患者平均预测概率&#xff09;-&#xff08;新模型非患者平均预测概率-旧模型非患者平均预测概率&#xff09…

Kafka第一课概述与安装

生产经验 面试重点 Broker面试重点 代码,开发重点 67 章了解 如何记录行为数据 1. Kafka概述 1.产生原因 前端 传到日志 日志传到Flume 传到HADOOP 但是如果数据特比大&#xff0c;HADOOP就承受不住了 2.Kafka解决问题 控流消峰 Flume传给Kafka 存到Kafka Hadoop 从Kafka…

IDE的下载和使用

IDE 文章目录 IDEJETBRAIN JETBRAIN 官网下载对应的ide 激活方式 dxm的电脑已经把这个脚本下载下来了&#xff0c;脚本是macjihuo 以后就不用买了

系列六、Redis中的五大数据类型及相关操作

一、五大数据类型 String类型、List类型、Set类型、ZSet类型、hash类型。 二、String类型 2.1、内存储存模型 2.2、常用操作命令 三、List类型 3.1、概述 list列表&#xff0c;相当于Java中的list集合。特点&#xff1a;元素有序 且 可以重复。 3.2、内存存储模型 3.3、常用…

“粤”动扬帆,共赢数安|2023百城巡展走进广深双城

新起点新战略共赢数安蓝海 2023美创科技百城巡展之旅如火如荼 持续赋能区域合作伙伴 8月10-11日&#xff0c;美创科技相继走进广州、深圳。作为2023年百城巡展之行的重要区域&#xff0c;美创为合作伙伴带来最新渠道政策解读&#xff0c;行业机会点及新产品新方案分享&#…

AIGC绘画:基于Stable Diffusion进行AI绘图

文章目录 AIGC深度学习模型绘画系统stable diffusion简介stable diffusion应用现状在线网站云端部署本地部署Stable Diffusion AIGC深度学习模型绘画系统 stable diffusion简介 Stable Diffusion是2022年发布的深度学习文本到图像生成模型&#xff0c;它主要用于根据文本的描述…

ChatGPT or BingChat

你相信我们对大模型也存在「迷信权威」吗&#xff1f; ChatGPT 的 GPT-4 名声在外&#xff0c;我们就不自觉地更相信它&#xff0c;优先使用它。但我用 ChatALL 比较 AI 大模型们这么久&#xff0c;得到的结论是&#xff1a; ChatGPT GPT-4 在大多数情况下确实是最强&#xf…

SSM整合(XML方式)

文章目录 SSM整合之后xml方式1 系统环境1.1 软件环境1.2 项目环境1.3 配置web.xml1.4 配置jdbc.properties文件1.5 配置SpringMVC核心文件1.6 配置Spring的核心文件1.7 配置MyBatis的核心文件1.8 配置数据库1.9 配置文件位置 2 编写后端代码2.1 编写实体类2.2 编写Dao接口2.3 编…

Postman接口自动化测试实战,从0到1一篇彻底打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 postman中的测试 …

【设计模式】责任链模式

顾名思义&#xff0c;责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;为请求创建了一个接收者对象的链。这种模式给予请求的类型&#xff0c;对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。 在这种模式中&#xff0c;通常每个接收者…

SegFormer之模型训练

单卡训练&#xff0c;所有配置文件里的【SyncBN】改为【BN】 启动训练 &#xff08;1&#xff09;终端直接运行 python tools/train.py local_configs/segformer/B1/segformer.b1.512x512.ade.160k.py &#xff08;2&#xff09;在编辑器中运行 在 [config] 前面加上’–‘将…

React源码解析18(6)------ 实现useState

摘要 在上一篇文章中&#xff0c;我们已经实现了函数组件。同时可以正常通过render进行渲染。 而通过之前的文章&#xff0c;beginWork和completeWork也已经有了基本的架子。现在我们可以去实现useState了。 实现之前&#xff0c;我们要先修改一下我们的index.js文件&#x…

从零开始,快速打造租车服务小程序的分享

随着移动互联网的发展&#xff0c;小程序成为了企业推广和服务的重要手段之一。租车服务行业也不例外&#xff0c;通过打造一款租车服务小程序&#xff0c;企业可以更好地与用户进行互动和交流&#xff0c;提供更方便快捷的租车服务。本文将介绍如何利用第三方制作平台/工具快速…

webpack 创建VUE项目

1、安装 node.js 下载地址&#xff1a;https://nodejs.org/en/ 下载完成以后点击安装&#xff0c;全部下一步即可 安装完成&#xff0c;输入命令验证 node -vnpm -v2.搭建VUE环境 输入命令&#xff0c;全局安装 npm install vue-cli -g安装完成后输入命令 查看 vue --ver…

HCIP-OpenStack搭建

1、OpenStack概述 OpenStack是一种云操作系统&#xff0c;OpenStack是虚拟机、裸金属和容器的云基础架构。可控制整个数据中心的大型计算、存储和网络资源池&#xff0c;所有资源都通过具有通用身份验证机制的API进行管理和配置。管理员也可通过Web界面控制&#xff0c;同时授…

【C语言】小游戏-扫雷(清屏+递归展开+标记)

大家好&#xff0c;我是深鱼~ 目录 一、游戏介绍 二、文件分装 三、代码实现步骤 1.制作简易游戏菜单 2. 初始化棋盘(11*11) 3.打印棋盘(9*9) 4.布置雷 5.计算(x,y)周围8个坐标的和 6.排查雷 <1>清屏后打印棋盘 <2>递归展开 <3>标记雷 四、完整代…

jupyter默认工作目录的更改

1、生成配置文件&#xff1a;打开Anaconda Prompt&#xff0c;输入如下命令 jupyter notebook --generate-config询问[y/N]时输入y 2、配置文件修改&#xff1a;根据打印路径打开配置文件jupyter_notebook_config.py&#xff0c;全文搜索找到notebook_dir所在位置。在单引号中…

vue3-vuex

一、概念 &#xff08;1&#xff09;Vuex 是一个状态和数据管理的框架&#xff0c;负责管理项目中多个组件和多个页面共享的数据。 &#xff08;2&#xff09;在开发项目的时候&#xff0c;我们就会把数据分成两个部分&#xff0c;一种数据是在某个组件内部使用&#xff0c;我…

数据库相关面试题

巩固基础&#xff0c;砥砺前行 。 只有不断重复&#xff0c;才能做到超越自己。 能坚持把简单的事情做到极致&#xff0c;也是不容易的。 mysql怎么优化 : MySQL的优化可以从以下几个方面入手&#xff1a; 数据库设计优化&#xff1a;合理设计表结构&#xff0c;选择合适的数…

《开放加速规范AI服务器设计指南》发布,应对生成式AI爆发算力挑战

8月10日&#xff0c;在2023年开放计算社区中国峰会(OCP China Day 2023)上&#xff0c;《开放加速规范AI服务器设计指南》&#xff08;以下简称《指南》&#xff09;发布。《指南》面向生成式AI应用场景&#xff0c;进一步发展和完善了开放加速规范AI服务器的设计理论和设计方法…