【C++入门到精通】C++入门 —— deque(STL)

在这里插入图片描述

阅读导航

  • 前言
  • 一、deque简介
    • 1. 概念
    • 2. 特点
  • 二、deque使用
    • 1. 基本操作(增、删、查、改)
    • 2. 底层结构
  • 三、deque的缺陷
  • 四、 为什么选择deque作为stack和queue的底层默认容器
  • 总结
  • 温馨提示

前言

文章绑定了VS平台下std::deque的源码,大家可以下载了解一下😍

前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的命名空间的一些知识点以及关于C++的缺省参数、函数重载,引用 和 内联函数也认识了什么是类和对象以及怎么去new一个 ‘对象’ ,以及学习了几个STL的结构也相信大家都掌握的不错,接下来博主将会带领大家继续学习有关C++比较重要的知识点—— deque(STL)。下面话不多说坐稳扶好咱们要开车了😍

一、deque简介

1. 概念

(官方文档介绍)

在C++中,deque(双端队列)是一种容器。deque是缩写形式,表示"double-ended queue",即双向队列。deque是C++标准库提供的一种方便、高效的双向队列容器,提供了在两端进行插入和删除操作的能力,同时支持随机访问
在这里插入图片描述

2. 特点

  1. 双向访问:deque允许在队列的两端进行插入和删除操作。这意味着你可以在队列的头部和尾部同时执行插入和删除操作,而不仅仅限制在一端。

  2. 动态大小:deque的大小是动态调整的,它可以根据需要自动增加或减少。这使得deque能够灵活地应对不同的数据量和操作需求。

  3. 高效插入和删除:与vector相比,在deque的头部和尾部进行插入和删除操作的时间复杂度是常数时间O(1)。这意味着deque对于频繁的插入和删除操作非常高效。

  4. 随机访问:与vector类似,deque也支持随机访问。你可以使用索引来访问deque中的元素,这使得deque在需要快速访问元素的情况下非常有用。

  5. 存储连续性:deque在内部使用一系列分段的固定大小数组来存储元素。每个分段都具有连续的内存,但这些分段之间不要求连续。这种内部结构使得deque能够提供高效的双向访问和动态大小调整。

二、deque使用

1. 基本操作(增、删、查、改)

  1. 插入元素:

    • push_back(value): 在deque的尾部插入一个元素。
    • push_front(value): 在deque的头部插入一个元素。
  2. 删除元素:

    • pop_back(): 删除deque的尾部元素。
    • pop_front(): 删除deque的头部元素。
  3. 访问元素:

    • front(): 返回deque的头部元素的引用。
    • back(): 返回deque的尾部元素的引用。
  4. 判断容器是否为空:

    • empty(): 如果deque为空,则返回true;否则返回false。
  5. 获取容器的大小:

    • size(): 返回deque中元素的个数。
  6. 清空容器:

    • clear(): 删除deque中的所有元素,使其变为空。
  7. 随机访问元素:

    • at(index): 返回位于指定索引位置的元素的引用,索引从0开始。
    • operator[](index): 返回位于指定索引位置的元素的引用。

下面是一些使用deque的基本代码:

#include <iostream>
#include <deque>int main() {std::deque<int> myDeque;// 插入元素myDeque.push_back(10);myDeque.push_front(5);// 访问元素std::cout << "Front element: " << myDeque.front() << std::endl;std::cout << "Back element: " << myDeque.back() << std::endl;// 删除元素myDeque.pop_back();myDeque.pop_front();// 判断容器是否为空if (myDeque.empty()) {std::cout << "Deque is empty" << std::endl;} else {std::cout << "Deque is not empty" << std::endl;}// 获取容器的大小std::cout << "Deque size: " << myDeque.size() << std::endl;// 清空容器myDeque.clear();return 0;
}

2. 底层结构

deque(双端队列)的底层结构通常由多个固定大小的缓冲区组成,每个缓冲区是一个连续的存储块。这些缓冲区通过一个指向前一个缓冲区和一个指向后一个缓冲区的指针进行连接,形成了一个双向链表

deque的内部缓冲区以分块的形式存储元素。每个缓冲区有一个固定的大小,它通常是2的幂次方,例如512、1024等。缓冲区中的元素被存储在数组中,以保持元素的连续性。

deque的双向链表由一个或多个缓冲区组成,每个缓冲区都包含一个指向前一个缓冲区和一个指向后一个缓冲区的指针。第一个缓冲区的指向前一个缓冲区的指针为空指针,最后一个缓冲区的指向后一个缓冲区的指针也为空指针

当需要在deque的头部或尾部插入或删除元素时,只涉及到相关缓冲区的操作,而不会涉及其他缓冲区。这种设计使得deque的插入和删除操作时间复杂度为常数级别(O(1))。

在这里插入图片描述
⭕部分源代码(详细代码在文件里)

namespace program_queue
{
template <class ContainerAllocator>
struct DequeueProgramRequest_
{typedef DequeueProgramRequest_<ContainerAllocator> Type;DequeueProgramRequest_(): token(0), id(0)  {}DequeueProgramRequest_(const ContainerAllocator& _alloc): token(0), id(0)  {(void)_alloc;}typedef uint64_t _token_type;_token_type token;typedef uint64_t _id_type;_id_type id;typedef boost::shared_ptr< ::program_queue::DequeueProgramRequest_<ContainerAllocator> > Ptr;typedef boost::shared_ptr< ::program_queue::DequeueProgramRequest_<ContainerAllocator> const> ConstPtr;}; // struct DequeueProgramRequest_
...............................

三、deque的缺陷

⭕deque(双端队列)在大多数情况下是非常高效且灵活的数据结构,但它也有一些缺点需要注意。

  1. 相对于vector,deque的内存占用更高:deque的底层实现通常由多个固定大小的缓冲区组成。这导致deque在存储元素时可能需要更多的内存空间,相对于vector而言。

  2. 不支持随机访问:尽管deque支持常数时间的插入和删除操作,但由于内部缓冲区是分块存储的,因此对于deque而言,随机访问的性能较差。在deque中进行随机访问需要根据元素的索引进行计算,而不是直接通过指针操作。

  3. 迭代器的失效:如果在deque中插入或删除元素,会导致原始deque的迭代器失效。这意味着在操作之前获取的迭代器可能不再有效,需要重新获取或使用新的迭代器。

  4. 对于大量元素的频繁插入和删除,效率较低:当大量元素需要在deque的中间位置插入或删除时,由于涉及到内存的重分配和数据的移动,deque的性能可能受到影响。

  5. 可能不利于缓存:由于deque的底层实现包含多个不相邻的缓冲区,这可能导致在连续访问元素时,对CPU缓存的使用效率不高。

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

  1. 高效的插入和删除操作:deque支持在队列的前端和后端进行高效的插入和删除操作。这对于实现stack的后进先出(LIFO)语义和queue的先进先出(FIFO)语义非常重要。

  2. 避免元素移动:相对于vector来说,deque的插入和删除操作不会引起元素的移动。而对于vector,当在前端插入或删除元素时,需要将整个元素序列进行移动;当在队列的末端插入或删除元素时,除了移动元素,还要考虑重新分配内存空间。这使得deque在插入和删除操作时更加高效。

  3. 动态大小调整:deque支持动态大小调整,可以根据需要自动增长或缩小存储空间。虽然这也是vector的特性,但由于deque的内部实现不需要进行元素的移动,所以在动态调整大小时,deque的性能更好。

  4. 同时提供栈和队列功能:由于deque既支持在队列的前端和后端进行插入和删除操作,也提供了随机访问的能力,因此可以同时满足栈和队列的需求。

⭕尽管deque有一些缺点,但这些缺点相对于deque在栈和队列操作中的优势来说是可以接受的。总体而言,deque作为stack和queue的底层默认容器是一个平衡性能和功能的选择。但是,也可以根据具体需要选择其他容器来实现stack和queue,例如vector或list,这取决于具体的使用场景和需求。

总结

首先,我们了解了deque的基本概念和特点,包括多个固定大小的缓冲区、双向链表连接以及高效的插入和删除操作。接着,我们深入探讨了deque的使用方法,包括基本操作和底层结构。其中,我们了解了如何进行增、删、查、改操作,以及deque由多个缓冲区组成的底层实现结构。此外,我们也提及了deque的一些缺陷,如内存占用较高、随机访问效率较低等。最后,我们解释了为何选择deque作为stack和queue的底层默认容器,包括高效的插入和删除操作、避免元素移动、动态大小调整等优势。然而,根据具体需求,我们也可以选择其他容器来实现相同的功能。

⭕总的来说,deque作为一种高效且灵活的数据结构,在栈和队列的实现中发挥着重要作用。通过了解deque的特点和使用方法,读者可以更好地理解和应用这一数据结构,并在实际开发中做出明智的选择。无论是作为stack还是queue的底层容器,deque在提供高效操作的同时,也带来了一些缺陷,因此需要根据具体的场景和需求来选择合适的数据结构。

温馨提示

感谢您对博主文章的关注与支持!在阅读本篇文章的同时,我们想提醒您留下您宝贵的意见和反馈。如果您喜欢这篇文章,可以点赞、评论和分享给您的同学,这将对我提供巨大的鼓励和支持。另外,我计划在未来的更新中持续探讨与本文相关的内容。我会为您带来更多关于C++以及编程技术问题的深入解析、应用案例和趣味玩法等。请继续关注博主的更新,不要错过任何精彩内容!

再次感谢您的支持和关注。我们期待与您建立更紧密的互动,共同探索C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!
在这里插入图片描述

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

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

相关文章

【C/C++】探索内存对齐的奥秘与优势

目录 一&#xff0c;前言 二&#xff0c;什么是内存对齐&#xff1f; 三&#xff0c;内存对齐的原理 四&#xff0c;内存对齐的优势 五&#xff0c;如何实现内存对齐&#xff1f;&#xff08;看这节就行&#xff09; 1.使用 #pragma pack 来实现内存对齐的示例 七&#…

R包开发-2.2:在RStudio中使用Rcpp制作R-Package(更新于2023.8.23)

目录 4-添加C函数 5-编辑元数据 6-启用Roxygen&#xff0c;执行文档化。 7-单元测试 8-在自己的计算机上安装R包&#xff1a; 9-程序发布 参考&#xff1a; 为什么要写这篇文章的更新日期&#xff1f;因为R语言发展很快&#xff0c;很多函数或者方式&#xff0c;现在可以使…

Yolo系列-yolov1

YOLO-V1 经典的one-stage方法 YouOnlyLookOnce&#xff0c;名字就已经说明了一切&#xff01;把检测问题转化成回归问题&#xff0c;一个CNN就搞定了&#xff01;可以对视频进行实时检测&#xff0c;应用领域非常广&#xff01; 核心思想&#xff1a; Yolov1的核心思想是将对象…

【Docker系列】Docker-核心概念/常用命令与项目部署实践

写在前面 Docker是一种开源的容器化技术&#xff0c;它允许开发者将应用程序及其依赖项打包到一个轻量级、可移植的容器中&#xff0c;从而实现快速部署和高效运行。Docker的核心概念包括镜像、容器、仓库等。本文将详细介绍Docker的基本概念、安装方法以及常用命令。 一、Doc…

搭建开发环境-WSL+Ubuntu(一键搭建开发环境)

概述 所谓工欲善其事必先利其器&#xff0c;搭环境往往是开发过程中卡出很多初学者的拦路虎。 对于很多老鸟来说&#xff0c;很多东西都已经习惯成自然&#xff0c;也就没有刻意和初学者说。但对于很多初学者&#xff0c;却是受益良多。 这个系列&#xff0c;先从操作系统开始…

前端工程化

早期混合开发&#xff1a; 1.沟通成本高 2.分工不明确 3.不变管理 4.不便维护和管理 前后端分离开发&#xff1a; 前端开发--------------&#xff08;请求/响应&#xff09;------------后端开发【依照接口文档&#xff08;原型需求&#xff09;】 需求分析-->接口定义--&g…

前端需要理解的工程化知识

1 Git 1.1 Git 常见工作流程 Git 有4个区域&#xff1a;工作区&#xff08;workspace)、index&#xff08;暂存区&#xff09;、repository&#xff08;本地仓库&#xff09;和remote&#xff08;远程仓库&#xff09;&#xff0c;而工作区就是指对文件发生更改的地方&#xff…

第一个VUE程序?

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title></head> <body><div id"app">{{message}} </div><!-- 1.导入Vue.js --> <script s…

matlab 根据索引提取点云

目录 一、语法二、说明三、名称-值对应参数1、输入参数2、输出参数四、代码示例五、结果展示六、参考链接一、语法 ptCloudOut = select(ptCloud,indices) ptCloudOut = select(ptCloud,row,column

如何使用HTML5新增的标签来优化SEO?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用HTML5新增的标签来优化SEO&#xff1f;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对…

【kubernetes】使用kubepshere部署中间件服务

KubeSphere部署中间件服务 入门使用KubeSphere部署单机版MySQL、Redis、RabbitMQ 记录一下搭建过程 (内容学习于尚硅谷云原生课程) 环境准备 VMware虚拟机k8s集群&#xff0c;一主两从&#xff0c;master也作为工作节点&#xff1b;KubeSphere k8skubesphere devops比较占用磁…

数据结构(基本概念和术语1)

数据、数据元素、数据项和数据对象 1.数据(Data) 是能输入计算机且能被计算机处理的各种符号的集合 信息的载体 是对客观事物符号化的表示能够被计算机识别、存储和加工 包括: 数值型的数据:整数、实数等 非数值型的数据:文字、图像、图形、声音等 2.数据元素(Data Eleme…

C#---第十九课:不同类型方法的执行顺序(new / virtual / common / override)

本文介绍不同类型的方法&#xff0c;在代码中的执行顺序问题&#xff1a; 构造方法普通方法&#xff08;暂用common代替&#xff09;、虚方法&#xff08;Virtual修饰&#xff09;、New方法&#xff08;new修饰&#xff09;三个优先级相同overide方法&#xff08;会替换virtual…

前端面试:【跨域与安全】跨域问题及解决方案

嗨&#xff0c;亲爱的Web开发者&#xff01;在构建现代Web应用时&#xff0c;跨域问题和安全性一直是不可忽视的挑战之一。本文将深入探讨跨域问题的背景以及解决方案&#xff0c;以确保你的应用既安全又能与其他域名的资源进行互操作。 1. 什么是跨域问题&#xff1f; 跨域问…

Go 自学:defer关键字

我们可以使用defer关键字延迟代码的执行&#xff0c;相当于我们把代码放入一个stack中&#xff0c;遵循last in first out的原则输出代码。 package mainimport ("fmt" )func myDefer() {for i : 0; i < 5; i {defer fmt.Print(i)} }func main() {defer fmt.Prin…

Elasticsearch配置优化

以下的优化基础是安装的 Elasticsearch 版本为 7.17.7&#xff0c;同时jdk版本为 1.8.321 1、jvm参数优化 这里说的jvm参数调优&#xff0c;是指elasticsearch安装目录下的jvm.options配置&#xff0c;如下图所示&#xff1a; 这里调整的内容主要是调整垃圾回收的收集器&#…

day16 代码回想录 二叉树03 二叉树的最大深度n叉树的最大深度二叉树的最小深度完全二叉树的节点个数

大纲 ● 104.二叉树的最大深度 ● 559.n叉树的最大深度 ● 111.二叉树的最小深度 ● 222.完全二叉树的节点个数 二叉树的最大深度 题目链接&#xff1a;104.二叉树的最大深度 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数 叶子节点是左右孩子节点都为空的节点 …

c#两个数进行交换

1.使用中间变量的形式 private static void Main(string[] args){int a110;int a220;ChangeNumber(ref a1,ref a2)onsole.WriteLine($"a1的值{a1},a2的值{a2}");Console.ReadLine();}public static void ChangeNumber(ref int a1, ref int a2){int temp a1;//temp10…

机器学习实战之模型的解释性:Scikit-Learn的SHAP和LIME库

概要 机器学习模型的“黑箱”困境 机器学习模型的崛起让我们惊叹不已&#xff01;不论是预测房价、识别图片中的猫狗&#xff0c;还是推荐给你喜欢的音乐&#xff0c;这些模型都表现得非常出色。但是&#xff0c;有没有想过&#xff0c;这些模型到底是如何做出这些决策的呢&a…

【实操干货】如何开始用Qt Widgets编程?(三)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 在本文中&#xff0…