<C++> STL_deque

<c++> STL_deque

1.deque的使用

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tp0r6ALo-1693144180150)(C:\Users\32784\AppData\Roaming\Typora\typora-user-images\image-20230827212550686.png)]

构造和析构

  • std::deque<T>:创建一个存储类型为 T 的元素的双端队列。
  • std::deque(const std::deque<T>& other):复制构造函数,用另一个双端队列初始化当前队列。
  • ~std::deque():析构函数,释放内存。

示例:

#include <iostream>
#include <deque>int main() {// 创建一个存储整数的双端队列std::deque<int> myDeque;// 在队尾插入元素myDeque.push_back(10);myDeque.push_back(20);myDeque.push_back(30);// 复制构造一个新的双端队列std::deque<int> anotherDeque = myDeque;// 输出原始队列的内容std::cout << "Original deque content:";for (const int& value : myDeque) {std::cout << " " << value;}std::cout << std::endl;// 输出复制构造的队列的内容std::cout << "Copied deque content:";for (const int& value : anotherDeque) {std::cout << " " << value;}std::cout << std::endl;// 注意:析构函数会在作用域结束时自动调用,释放内存return 0;
}

容量相关

  • size():返回队列中元素的数量。
  • empty():检查队列是否为空。

示例:

#include <deque>
#include <iostream>int main() {std::deque<int> myDeque = {10, 20, 30, 40};std::cout << myDeque.size() << std::endl; //4std::cout << myDeque.empty() << std::endl;//0return 0;
}
  • resize(new_size):调整队列的大小。
void resize(size_type count); 
void resize(size_type count, const value_type& value);
  • count:新的队列大小。
  • value:在增加队列大小时用于填充新元素的默认值。

功能:

  • 如果 count 小于当前队列的大小,resize 会移除尾部的元素,使队列的大小变为 count
  • 如果 count 大于当前队列的大小,resize 会在尾部插入足够数量的默认值为 value 的元素,使队列的大小变为 count

示例:

#include <iostream>
#include <deque>int main() {std::deque<int> myDeque = {10, 20, 30};// 调整队列大小为 5,填充默认值 0myDeque.resize(5);for (const int& value : myDeque) {std::cout << " " << value;   // 10 20 30 0 0}std::cout << std::endl;// 调整队列大小为 3myDeque.resize(3);for (const int& value : myDeque) {std::cout << " " << value;  // 10 20 30}std::cout << std::endl;return 0;
}

元素访问

  • at(index):函数返回指定索引处的元素,并在访问之前进行范围检查。如果索引超出了双端队列的有效范围,将引发 std::out_of_range 异常。
  • operator[](index):运算符返回指定索引处的元素,但不进行范围检查。如果索引超出了有效范围,行为将是未定义的。
  • front():返回第一个元素的引用。
  • back():返回最后一个元素的引用。

示例:

#include <deque>
#include <iostream>int main() {// 创建一个存储字符串的双端队列std::deque<std::string> myDeque;// 在队尾插入元素myDeque.push_back("Alice");myDeque.push_back("Bob");myDeque.push_back("Charlie");// 使用 at(index) 进行范围安全的访问try {std::string value = myDeque.at(1);// 索引1处的元素是 "Bob"std::cout << value << std::endl;  //Bob} catch (const std::out_of_range &e) {std::cout << "Index is out of range." << std::endl;}// 使用 operator[](index) 进行不安全的访问std::string unsafeValue = myDeque[2];// 索引2处的元素是 "Charlie"std::cout << "不安全: " << unsafeValue << std::endl;// 使用 front() 访问第一个元素std::string firstElement = myDeque.front();std::cout << firstElement << std::endl;// 使用 back() 访问最后一个元素std::string lastElement = myDeque.back();   //Alicestd::cout << lastElement << std::endl;      //Charliereturn 0;
}

修改操作

  • push_back(value):在队尾插入一个元素。
  • push_front(value):在队首插入一个元素。
  • pop_back():移除队尾的元素。
  • pop_front():移除队首的元素。
  • insert(pos, value):在指定位置插入一个元素。
  • erase(pos):移除指定位置的元素。
  • clear():移除所有元素。

示例:

#include <deque>
#include <iostream>int main() {std::deque<int> myDeque;// 在队尾插入元素myDeque.push_back(10);myDeque.push_back(20);// 在队首插入元素myDeque.push_front(5);// 输出队列内容for (const int &value: myDeque) {std::cout << value << " ";//5 10 20}std::cout << std::endl;// 移除队尾的元素myDeque.pop_back();// 移除队首的元素myDeque.pop_front();// 输出队列内容for (const int &value: myDeque) {std::cout << value << " ";//10}std::cout << std::endl;// 在指定位置插入元素std::deque<int>::iterator it = myDeque.insert(myDeque.begin() + 1, 15);// 输出队列内容for (const int &value: myDeque) {std::cout << value << " ";//10 15}std::cout << std::endl;// 移除指定位置的元素myDeque.erase(it);// 输出队列内容for (const int &value: myDeque) {std::cout << value << " ";//10}std::cout << std::endl;// 清空队列myDeque.clear();if (myDeque.empty()) {std::cout << "Deque is empty.";} else {std::cout << "Deque is not empty.";}std::cout << std::endl;return 0;
}

迭代器

  • begin()end():返回指向第一个元素和尾后元素的迭代器。

示例:

#include <iostream>
#include <deque>int main() {std::deque<int> myDeque = {10, 20, 30, 40};for (std::deque<int>::iterator it = myDeque.begin(); it != myDeque.end(); ++it) {std::cout << " " << *it;  //10 20 30 40}std::cout << std::endl;return 0;
}
  • rbegin()rend():返回指向最后一个元素和首元素前一个位置的逆向迭代器。

示例:

#include <iostream>
#include <deque>int main() {std::deque<int> myDeque = {10, 20, 30, 40};for (std::deque<int>::reverse_iterator rit = myDeque.rbegin(); rit != myDeque.rend(); ++rit) {std::cout << " " << *rit;   //40 30 20 10}std::cout << std::endl;return 0;
}

2.deque的原理介绍

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

在这里插入图片描述

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

在这里插入图片描述

那deque是如何借助其迭代器维护其假想连续的结构呢?

在这里插入图片描述

3.deque的优缺点

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

4.为什么选择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的优点,而完美的避开了其缺陷。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

基于SSM+Bootstrap+MySQL+JSP的艺术品古玩交易销售系统

项目运行截图 销售首页 热销推荐 古玩详情 用户注册 用户登录 订单订单 商品管理 分类管理 条幅推荐 修改密码 管理员登录 购物车 收货订单 我的订单 个人中心 技术描述 开发工具&#xff1a; Idea/Eclipse 数据库&#xff1a; mysql Jar包仓库&#xff1a; Maven 前段框架&am…

【开题报告】springboot成都市古玩线上服务平台1x2ji计算机毕业设计

本项目包含程序源码数据库LW调试部署环境&#xff0c;文末可获取一份本项目的java源码和数据库参考。 开题报告 研究背景&#xff1a; 随着互联网的快速发展和普及&#xff0c;线上服务平台在各个领域得到了广泛应用。古玩行业作为一种传统文化产业&#xff0c;也需要适应时代…

JVM第三篇 运行时数据区-虚拟机栈和PC程序计数器

目录 1. JAVA中的线程 2. 栈区 2.1 栈帧 2.2 栈可能出现的异常 2.3 设置栈大小 3.程序计数器&#xff08;PC&#xff09; 4. PC和栈发挥的作用 5. 关于栈的常见面试题 虚拟机包含三大部分&#xff0c;类加载子系统&#xff0c;运行时数据区&#xff0c;执行引擎。运行时…

智慧监狱整体解决方案PPT

导读&#xff1a;原文《智慧监狱整体解决方案PPT》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 喜欢文章&#xff0c;您可以点赞评论转发本文&#xff0c;了解更多…

Linux设备驱动之多个同类设备共用一套驱动

1. 应用场景 比如我们的设备上有很多一样的usb接口&#xff0c;这些usb接口都需要有驱动才能工作&#xff0c;那么是每个usb都一套单独的驱动程序么&#xff1f;显然不是的&#xff0c;这些usb接口属于同一类设备&#xff0c;用户对他们的操作方法完全一致&#xff0c;只不过不…

ScheduleJS Crack,新的“信息列”水平滚动功能

ScheduleJS Crack,新的“信息列”水平滚动功能 增加了对Angular 16的支持 新的“信息列”水平滚动功能。 新的“信息列”固定功能。 添加了输入属性以处理组件模板中的偶数和奇数ScheduleRowPlainBackgroundColor以及CSS变量。 改进了“信息列”和角度甘特组件的类型。 Schedul…

Unity3D开发之发布webplayer设置全屏

项目打包出来后会出现一个html文件&#xff0c;使用notepad打开&#xff0c;删除部分代码 并增加一些代码可设置全屏。 <style type"text/css">#unityPlayer {float:left;top: 0px; height: 100%; width: 100%;position: relative;}html,body{overflow-y:hidde…

web player php,unity web player是什么软件

unity web player是一款浏览器运行Unity3D游戏引擎发布的游戏的插件&#xff0c;一般是用户在玩游戏的时候系统自动安装的&#xff1b;通过unity web player插件可以发布web平台的游戏。 本文操作环境&#xff1a;Windows7系统&#xff0c;Dell G3电脑。 推荐&#xff1a;《编程…

软考高级系统架构设计师真题练习(一)计算机组成结构

【原文链接】软考高级系统架构设计师真题练习&#xff08;一&#xff09;计算机组成结构 真题练习 1 答案&#xff1a;B 真题练习 2 答案&#xff1a;C 真题练习 3 答案&#xff1a;A 真题练习 4 答案&#xff1a;A、D 真题练习 5 答案&#xff1a;D 真题练习 …

C语言(第三十天)

1. 什么是bug bug本意是昆虫”或“虫子”&#xff0c;现在一般是指在电脑系统或程序中&#xff0c;隐藏着的一些未被发现的缺陷或问 题&#xff0c;简称程序漏洞。 “Bug” 的创始人格蕾丝赫柏&#xff08;Grace Murray Hopper&#xff09;&#xff0c;她是一位为美国海军工作的…

QQ互联申请及配置

QQ互联申请及配置 今天要说的只是针对QQ互联的操作&#xff0c;其他的互联请参考相关网站。 第一步&#xff1a;需要申请API接口的两码 自行登录QQ互联https://connect.qq.com/index.html&#xff0c;然后按照要求申请就OK啦。 过几天你会收到一封审核通过的邮件&#xff1a; …

C、C++、VC、MFC网页自动注册、登陆、发帖、留言 QQ注册、QQ申请器源码、源代码

查看文章 【转】C、C、VC、MFC网页自动注册、登陆、发帖、留言 QQ注册、QQ申请器源码、源代码 2012-01-11 10:58 转载自 qq316293804 最终编辑 qq316293804 参考资料&#xff1a; 自动登录yahoo邮箱http://blog.csdn.net/suisuibianbian/archive/2005/12/12/550260.aspx VC采集…

激活函数总结(二十一):激活函数补充(APL、Inverse Cubic)

激活函数总结&#xff08;二十一&#xff09;&#xff1a;激活函数补充 1 引言2 激活函数2.1 Adaptive piecewise linear&#xff08;APL&#xff09;激活函数2.2 Inverse Cubic激活函数 3. 总结 1 引言 在前面的文章中已经介绍了介绍了一系列激活函数 (Sigmoid、Tanh、ReLU、…

mozilla美国工程师两秒钟制造百度山寨版

周三下午清华科技园的一个咖啡屋&#xff0c;我和几位国内的blogger–刘兴亮、老杳、詹鹏与mozilla组织的两位美国工程师Aza Raskin 、Dan Mills相聚。两位工程师给我们介绍mozilla全球组织和基金会&#xff0c;还给我们演示了很多超级酷的firefox插件&#xff0c;两个多小时的…

热点故事“百度C2C是“社会化商务”的重大利好”

17号下午&#xff0c;传出了百度C2C的消息&#xff0c;一天之内炸开了锅。 玩聚网象techmeme一样的行动起来&#xff0c;自动语义聚合出来了这个玩聚热点故事- 百度C2C是“社会化商务”的重大利好&#xff0c;一时间麦田的、詹鹏的、wkcow的等一大堆blogger的评论都进来了。百度…

BIOS中的内存测试memtest

参考&#xff1a; https://blog.csdn.net/evenness/article/details/7818857 https://blog.csdn.net/skdkjzz/article/details/17073455 https://blog.csdn.net/sannik/article/details/8930625# 在 U-Boot中&#xff0c;Denx&#xff08;U-Boot的开发商&#xff09;针对常见…

Win系统 - 内存稳定性测试软件(MemTest)

给大家介绍一款免安装的内存稳定性测试软件--MemTest&#xff0c;它不但可以彻底的检测出内存的稳定度&#xff0c;还可同时测试记忆的储存与检索资料的能力&#xff0c;memtest pro汉化版软件体积小巧&#xff0c;绿色免安装&#xff0c;使用简单&#xff0c;有兴趣的小伙伴们…

[Linux] VMware虚拟机开机后直接进入memtest

问题描述 今天碰到一个很难受的问题&#xff0c;昨天写报告的时候虚拟机还是正常的&#xff0c;早上开机的时候忽然报错进不了ubuntu虚拟机直接进入一个memtest的界面&#xff0c;情况大概是这样的&#xff1a; 一开始会报一些“error syntax”“error incorrect command”等错…

内存稳定性测试软件(MemTest)

给大家介绍一款免安装的内存稳定性测试软件--MemTest&#xff0c;它不但可以彻底的检测出内存的稳定度&#xff0c;还可同时测试记忆的储存与检索资料的能力&#xff0c;memtest pro汉化版软件体积小巧&#xff0c;绿色免安装&#xff0c;使用简单&#xff0c;有兴趣的小伙伴们…

MemTest内存软件测试介绍说明-2

有很多测试内存的软件。但是&#xff0c;许多测试只是将一些模式套用到内存上&#xff0c;而没有对内存体系结构或如何最好地检测错误进行深入思考或了解。这对于硬盘故障很有效&#xff0c;但很少发现间歇性错误。基于 BIOS 的内存测试对于查找间歇性内存错误毫无用处。 存储…