STL——stack和queue

一、stack和queue

stl中提供了栈和队列配接器供我们使用,以后就可以直接使用了。不需要我们自己造轮子。

使用细节参考文档就可以,与之学过的容器并无二致。栈和队列的特性我们再学习数据结构时已经了解了。这里就不在赘述了。

stack - C++ Reference (cplusplus.com)

queue - C++ Reference (cplusplus.com)

这里有几个题可供我们练习一下:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

栈的压入、弹出序列_牛客题霸_牛客网

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

在模拟实现stack和queue,我们先了解一下容器适配器;什么是适配器呢?

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

stl标准库中stack和queue的底层结构就是使用了适配器模式;虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque(双端队列)下面介绍

stack的模拟实现

    template<class T, class Con = deque<int>>class stack{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}int size(){return _con.size();}T& top(){return _con.back();}bool empty(){return _con.empty();}private:Con _con;};

queue模拟实现

    //双端队列适合进行两端插入删除操作,不适合在中间插入。//相较于vector来说,扩容更好一点。//相较于list来说,支持随机访问template<class T, class Con = deque<T>>//默认类型是双端队列class queue{public:void push(const T& x){_con.push_back(x);}void pop(){//_con.erase(_con.begin());  //vector没有pop_front_con.pop_front();          }int size(){return _con.size();}T& front(){return _con.front();}T& back(){return _con.back();}bool empty(){return _con.empty();}private:Con _con;};

二、deque——双端队列

deque概念

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

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

双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问的假象,落在了deque的迭代器身上,因此deque的迭代器设计就比较复杂,如下图所示:

deque的缺陷:

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

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

  • stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或两端操作。
  • 在stack中元素增长时,deque比vector效率高(扩容时不需要搬移大量数据),queue中的元素增长时,deque不仅效率高,而且内存使用率高。

三、priority_queue——优先级队列

priority_queue概念

priority_queue - C++ Reference (cplusplus.com)

priority_queue也是一个容器适配器,用vector实现的。

priority_queue底层采用的数据结构是堆(默认是大堆)。

 因为这里使用了仿函数,调用的是less这个类,所以是大堆。

练习: 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

什么是仿函数

仿函数就是使用起来类似于使用一个函数,但是它实际上不是调用函数,而是通过类的对象调用类中重载的括号运算符成员函数,从而达到我们的目的。

仿函数可以作为模板参数使用,因为每个仿函数都拥有自己的类型。

仿函数比一般函数更灵活。

priority_queue模拟实现

    template<class T>struct Less{bool operator()(const T& x, const T& y){return x < y;}};template<class T>struct Greater{bool operator()(const T& x, const T& y){return x > y;}};    template<class T, class Con = vector<T>, class Compare = Less<T>>class priority_queue{private://向下调整建堆,建大堆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;}else{break;}}}void Adjust_up(int child){Compare com;int parent = (child - 1) / 2;while (child > 0){if (com(_con[parent], _con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}public:template<class InputIterator>priority_queue(InputIterator first, InputIterator last){while (first != last){_con.push_back(*first);++first;}for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--){Adjust_down(i);}}priority_queue(){}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);}size_t size() const {return _con.size();}bool empty() const{return _con.empty();}const T& top(){return _con[0];}private:Con _con;};

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

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

相关文章

vite+vue3项目配置cdn引入在线依赖

采用ejs的方式 安装语法依赖 npm install vite-plugin-ejs -D配置暴露数据 vite.config.js文件&#xff1a; import { fileURLToPath, URL } from node:url import { defineConfig, loadEnv } from vite import vue from vitejs/plugin-vue import vueJsx from vitejs/plug…

分布式锁实现方式

分布式锁 1 分布式锁介绍 1.1 什么是分布式 一个大型的系统往往被分为几个子系统来做&#xff0c;一个子系统可以部署在一台机器的多个 JVM(java虚拟机) 上&#xff0c;也可以部署在多台机器上。但是每一个系统不是独立的&#xff0c;不是完全独立的。需要相互通信&#xff…

vue 关闭prettier警告warn

这个就是我们创建vue cli的时候 把这个给默认上了 关闭这个只需在.eslintrc.js页面里边添加一行代码"prettier/prettier": "off"

34.Netty源码之Netty如何处理网络请求

highlight: arduino-light 通过前面两节源码课程的学习&#xff0c;我们知道 Netty 在服务端启动时会为创建 NioServerSocketChannel&#xff0c;当客户端新连接接入时又会创建 NioSocketChannel&#xff0c;不管是服务端还是客户端 Channel&#xff0c;在创建时都会初始化自己…

线程池原理

一、线程池的定义 线程池&#xff0c;按照配置参数&#xff08;核心线程数、最大线程数等&#xff09;创建并管理若干线程对象&#xff0c;没有任务的时候&#xff0c;这些线程都处于等待空闲状态。如果有新的线程任务&#xff0c;就分配一个空闲线程执行。如果所有线程都处于…

【NX】NX二次开发BlockUI集列表的详细使用步骤

最近使用NX二次开发&#xff0c;需要用到集列表&#xff0c;也就是SetList这个控件&#xff0c;然而网上相关的资料和范例实在是太少&#xff0c;有幸找到《NX二次开发-BlockUI集列表的使用技巧》和《UG&#xff08;NX&#xff09;二次开发 BlockUI 集列表使用方法》&#xff0…

Dubbo使用

<!--dubbo--><dependency><groupId>com.alibaba.spring.boot</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.0.0</version></dependency>接口 public interface IUseService {public String…

设计模式之状态模式(State)的C++实现

1、状态模式的提出 在组件功能开发过程中&#xff0c;某些对象的状态经常面临变化&#xff0c;不同的状态&#xff0c;其对象的操作行为不同。比如根据状态写的if else条件情况&#xff0c;且这种条件变化是经常变化的&#xff0c;这样的代码不易维护。可以使用状态模式解决这…

安全学习DAY16_信息打点-CDN绕过

信息打点-CDN绕过 文章目录 信息打点-CDN绕过本节思维导图相关链接&工具站&项目工具前置知识&#xff1a;CDN配置&#xff1a;配置1&#xff1a;加速域名-需要启用加速的域名配置2&#xff1a;加速区域-需要启用加速的地区配置3&#xff1a;加速类型-需要启用加速的资源…

VGG分类实战:猫狗分类

关于数据集 数据集选择的是Kaggle上的Cat and Dog&#xff0c;猫狗图片数量上达到了上万张。你可以通过这里进入Kaggle下载数据集Cat and Dog | Kaggle。 在我的Github仓库当中也放了猫狗图片各666张。 VGG网络 VGG的主要特点是使用了一系列具有相同尺寸 3x3 大小的卷积核进…

vue3生命周期

原理 vue3也提供了Composition API形式的生命周期钩子&#xff0c;与vue2.x中钩子对应关系如下&#xff1a; beforeCreate setup&#xff08;&#xff09; created setup&#xff08;&#xff09; beforeMountonBeforeMount mountedonMounted beforeUpdateonBeforeUpdate updat…

【C++】做一个飞机空战小游戏(十)——子弹击落炮弹、炮弹与飞机相撞

[导读]本系列博文内容链接如下&#xff1a; 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞…

Unsafe upfileupload

文章目录 client checkMIME Typegetimagesize 文件上传功能在web应用系统很常见&#xff0c;比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后&#xff0c;后台会对上传的文件进行判断 比如是否是指定的类型、后缀名、大小等等&#xff0c;然后将其按…

HTML中的字符串转义

为什么要转义&#xff1f; 转义可以防止 xss 攻击。接下来&#xff0c;我们来看一下如何转义。 HTML Sanitizer API Sanitizer 是浏览器自带的转义方法&#xff0c;在2021年初被提出&#xff0c;兼容性问题很大。 列举几个常用的 API&#xff1a; const $div document.qu…

【广州华锐视点】VR线上教学资源平台提供定制化虚拟现实学习内容

虚拟现实&#xff08;VR&#xff09;技术的出现为我们提供了一种全新的在线教学方式。由广州华锐视点开发的VR线上教学资源平台&#xff0c;作为一个综合性的学习工具&#xff0c;正在教育领域迅速发展&#xff0c;并被越来越多的教育机构和学生所接受。那么&#xff0c;VR线上…

redis实战-缓存数据解决缓存与数据库数据一致性

缓存的定义 缓存(Cache),就是数据交换的缓冲区,俗称的缓存就是缓冲区内的数据,一般从数据库中获取,存储于本地代码。防止过高的数据访问猛冲系统,导致其操作线程无法及时处理信息而瘫痪&#xff0c;这在实际开发中对企业讲,对产品口碑,用户评价都是致命的;所以企业非常重视缓存…

ReactNative进阶(三十四):ipa Archive 阶段报错error: Multiple commands produce问题修复及思考

文章目录 一、前言二、问题描述三、问题解决四、拓展阅读五、拓展阅读 一、前言 在应用RN开发跨平台APP阶段&#xff0c;从git中拉取项目&#xff0c;应用Jenkins进行组包时&#xff0c;发现最终生成的ipa安装包版本号始终与项目中设置的版本号不一致。 二、问题描述 经过仔…

图数据库_Neo4j和SpringBoot整合使用_实战创建明星关系图谱---Neo4j图数据库工作笔记0010

然后我们再来看一下这个明星关系图谱 可以看到这里 这个是原来的startRelation 我们可以写CQL去查询对应的关系 可以看到,首先查询出来以后,然后就可以去创建 我们可以把写的创建明星关系的CQL,拿到 springboot中去执行 可以看到,这里我们先写一个StarRelationRepository,然…

【100天精通python】Day42:python网络爬虫开发_HTTP请求库requests 常用语法与实战

目录 1 HTTP协议 2 HTTP与HTTPS 3 HTTP请求过程 3.1 HTTP请求过程 3.2 GET请求与POST请求 3.3 常用请求报头 3.4 HTTP响应 4 HTTP请求库requests 常用语法 4.1 发送GET请求 4.2 发送POST请求 4.3 请求参数和头部 4.4 编码格式 4.5 requests高级操作-文件上传 4.6 …

机器学习之数据集

目录 1、简介 2、可用数据集 3、scikit-learn数据集API 3.1、小数据集 3.2、大数据集 4、数据集使用 ⭐所属专栏&#xff1a;人工智能 文中提到的代码如有需要可以私信我发给你&#x1f60a; 1、简介 当谈论数据集时&#xff0c;通常是指在机器学习和数据分析中使用的一组…