C++ STL之deque的理解及使用

文章目录

  • 1. 介绍
  • 2. 实现原理(简单理解)
  • 3. deque的优缺点
  • 4. deque类的使用
    • 4.1 deque类对象的构造函数
    • 4.2 deque类对象的容量操作
    • 4.3 deque类对象的修改操作
    • 4.4 deque类对象的访问及遍历操作


1. 介绍

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

在这里插入图片描述

2. 实现原理(简单理解)

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

在这里插入图片描述

这里如果中控数组满了,扩容的代价是很低的,只需要将指针变量数组扩容即可。

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

在这里插入图片描述

3. 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 没有迭代器),只需要在固定的一端或者两端进行操作,使用deque效率很高。

  2. 在 stack 中元素增长时,deque 比 vector 的效率高(扩容时不需要搬移大量数据);queue 中的元素增长时,deque 不仅效率高,而且内存使用率高。

所以 stack 和 queue 结合了 deque 的优点,而完美的避开了其缺陷。

4. deque类的使用

4.1 deque类对象的构造函数

(constructor)构造函数代码功能说明
explicit deque (const allocator_type& alloc = allocator_type());(默认构造函数)构造一个空的容器,没有任何元素。
explicit deque (size_type n, const value_type& val = value_type(), onst allocator_type& alloc = allocator_type());(填充构造函数)构造一个包含 n 个元素的容器,每个元素都是 val 的副本。
template <class InputIterator>
deque (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
(范围构造函数)根据范围[first, last)中的元素构造一个容器,容器中的元素个数与该范围中的元素个数相同,并且顺序相同。
deque (const deque& x);(拷贝构造函数)构造一个容器,其中的每个元素都是 x 中对应元素的副本,顺序相同。

4.2 deque类对象的容量操作

函数名称代码功能说明
sizesize_type size() const;返回 deque 容器中元素个数。
max_sizesize_type max_size() const;返回 deque 容器可以容纳最大元素个数。
resizevoid resize (size_type n, value_type val = value_type());调整容器的大小,使其包含 n 个元素。如果 n 小于当前容器的大小,容器的内容将被减少到前 n 个元素,移除超出范围的元素。如果 n 大于当前容器的大小,容器的内容将通过在末尾插入足够数量的元素来扩展到大小为 n。如果指定了 val,新插入的元素将被初始化为 val 的副本;否则,它们将进行值初始化。
emptybool empty() const;返回 deque 容器是否为空(即其大小是否为 0)。

4.3 deque类对象的修改操作

函数名称代码功能说明
push_backvoid push_back (const value_type& val);在 deque 容器开头插入一个新元素 val。
push_frontvoid push_front (const value_type& val);在 deque 容器开头插入一个新元素 val。
pop_backvoid pop_back();删除最后一个元素。
pop_frontvoid pop_front();删除第一个元素。
insertiterator insert (iterator position, const value_type& val);
void insert (iterator position, size_type n, const value_type& val);
template <class InputIterator>
void insert (iterator position, InputIterator first, InputIterator last);
在指定位置 position 之前插入新元素 val、n 个 val或者迭代器区间[first, last)范围的元素。
eraseiterator erase (iterator position);
iterator erase (iterator first, iterator last);
删除 position 位置的元素或者迭代器区间[first, last)范围的元素。
swapvoid swap (deque& x);与另一个相同类型的 deque 容器 x 交换内容。存在一个同名的非成员函数 swap,重载该算法的意义是优化交换时间。
clearvoid clear();从 deque 容器中移除所有元素,使容器的大小变为0。

4.4 deque类对象的访问及遍历操作

函数名称代码功能说明
operator[]reference operator[] (size_type n);
const_reference operator[] (size_type n) const;
返回 deque 容器中位置 n 处的元素的引用。
at reference at (size_type n);
const_reference at (size_type n) const;
返回 deque 容器中位置 n 处的元素的引用。该函数会自动检查 n 是否在 deque 容器的有效元素范围内,如果不在范围内(即 n 大于或等于向量的大小),则抛出 out_of_range 异常。这与成员运算符 operator[] 不同,后者不进行边界检查。
frontreference front();
const_reference front() const;
返回 deque 容器中第一个元素的引用。
backreference back();
const_reference back() const;
返回 deque 容器中最后一个元素的引用。

遍历操作

遍历操作

#include <iostream>
#include <deque>int main()
{std::deque<int> dq(10, 100);// 1.普通下标遍历for (size_t i = 0; i < dq.size(); ++i)std::cout << dq[i] << " ";std::cout << '\n';// 2.迭代器遍历for (std::deque<int>::iterator it = dq.begin(); it != dq.end(); ++it)std::cout << *it << " ";std::cout << '\n';// 3.范围for遍历for (auto e : dq)std::cout << e << " ";std::cout << '\n';return 0;
}

输出结果

在这里插入图片描述

说明

  1. 普通下标遍历:
    在此代码段中,通过使用普通的下标操作符 [],从索引 0 开始,逐个访问 deque 容器dq 中的元素,并将其打印出来。循环变量 i 从 0 递增到 dq.size()-1,并使用 dq[i] 访问每个元素。最后,打印一个换行符。
  2. 迭代器遍历:
    在此代码段中,使用迭代器进行遍历。首先,通过 dq.begin() 获取 deque 容器 dq 的起始迭代器,通过 dq.end() 获取 deque 容器 dq 的结束迭代器。然后,通过迭代器 it 遍历从起始迭代器到结束迭代器之间的所有元素,并使用 *it 打印每个元素的值。最后,打印一个换行符。
  3. 范围for循环遍历:
    在此代码段中,使用范围for循环对 deque 容器 dq 进行遍历。对于 deque 容器 dq 中的每个元素,将其依次赋值给循环变量 e,然后打印出 e 的值。此方法不需要显式地使用迭代器或下标来访问向量的元素,因为范围for循环会自动处理迭代过程,并在每次迭代中将元素赋值给循环变量。最后,打印一个换行符。

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

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

相关文章

MATLAB curve fitting toolbox没有怎么办?

版本&#xff1a;MATLAB R2023b 如果在安装MATLAB时仅仅选择了安装MATLAB&#xff0c;而并未选择其他选项&#xff0c;则在进入MATLAB后会发现顶部的APP栏中无法找到曲线拟合工具箱。 本人跟随MATLAB中的教程进行下载时&#xff0c;出现了如下报错&#xff1a; 最终解决方案&a…

【SVD生成视频+可本地部署】ComfyUI使用(二)——使用Stable Video Diffusion生成视频 (2023.11开源)

SVD官方主页 &#xff1a; Huggingface | | Stability.ai || 论文地址 huggingface在线运行demo : https://huggingface.co/spaces/multimodalart/stable-video-diffusion SVD开源代码&#xff1a;Github&#xff08;含其他项目&#xff09; || Huggingface 在Comfyui使用&…

MIT_线性代数笔记:线性代数常用概念及术语总结

目录 1.系数矩阵2.高斯消元法3.置换矩阵 Permutation4.逆矩阵 Inverse 1.系数矩阵 线性代数的基本问题就是解 n 元一次方程组。例如&#xff1a;二元一次方程组 2 x − y 0 − x 2 y 3 \begin{align*} & 2x - y 0\\ & -x2y 3 \end{align*} ​2x−y0−x2y3​ 写成…

谷歌公布一个可以让 AI 进行自我判断输出内容正确性的模型训练框架 ASPIRE

谷歌开发了一款名为 ASPIRE 的训练框架&#xff0c;旨在增强人工智能&#xff08;AI&#xff09;模型的选择性预测能力。这款框架为模型引入了 “可信度” 机制&#xff0c;即模型会输出一系列答案&#xff0c;并为每个答案赋予一个正确概率评分。通过这种方式&#xff0c;ASPI…

经典面试题-死锁

目录 1.什么是死锁&#xff1f; 2.形成死锁的四个必要条件 3.死锁的三种情况 第一种情况&#xff1a; 举例&#xff1a; 举例&#xff1a; 第二种情况&#xff1a;两个线程 两把锁 举例&#xff1a; 第三种情况&#xff1a;N个线程 M把锁 哲学家进餐问题 1.什么是死锁&…

Linux破解密码

破解root密码&#xff08;Linux 7&#xff09; 1、先重启——e 2、Linux 16这一行 末尾加rd.break&#xff08;不要回车&#xff09;中断加载内核 3、再ctrlx启动&#xff0c;进入救援模式 4、mount -o remount&#xff0c;rw /sysroot/——&#xff08;mount挂载 o——opti…

选择海外云手机需要考虑什么?

随着跨境电商行业的蓬勃发展&#xff0c;企业们纷纷寻找提升平台流量和广告投放效果的方法&#xff0c;这已成为业界的当务之急。传统的宣传模式在国内受到直播和链接带货等新兴方式的冲击&#xff0c;而在国外&#xff0c;类似的趋势也在悄然兴起&#xff0c;呈现出广阔的发展…

服务器运维小技巧(二)——如何进行监控告警

服务器运维难度高的原因&#xff0c;很大程度是因为服务器一旦出现问题&#xff0c;生产环境的业务就会受到严重影响&#xff0c;极有可能带来难以承担的后果。因此这份工作要求工程师保持高要求的服务质量&#xff0c;能够快速响应问题&#xff0c;及时解决问题。 但是“及时…

Eureka-第一篇

​ 一、Eureka的概述 Eureka的基本概念和作用 Eureka是一个基于REST的服务&#xff0c;主要用于定位运行在AWS域中的中间层服务&#xff0c;以达到负载均衡和中间层服务故障转移的目的。Eureka是Netflix开发的服务发现框架&#xff0c;主要用于解决在云计算环境中动态位置服…

[docker] Docker镜像的创建以及Dockerfile的使用

一、Dokcer镜像的创建 创建镜像有三种方法&#xff0c;分别为基于已有镜像创建、基于本地模板创建以及基于Dockerfile创建。 1.1 基于现有镜像创建 &#xff08;1&#xff09;首先启动一个镜像&#xff0c;在容器里做修改docker run -it --name web centos:7 /bin/bash …

【C++】介绍STL中list容器的常用接口

目录 一、STL中的list简介 二、构造函数 2.1 默认构造函数 2.2 填充构造&#xff08;用n个相同的值构造&#xff09; 2.3 迭代器构造 2.4 拷贝构造和赋值运算符重载 三、迭代器 3.1 正向迭代器 3.2 反向迭代器 四、容量相关 4.1 获取list中有效数据的个数 4.2 判…

android camera的使用以及输出的图像格式

一、Camera 1.1、结合SurfaceView实现预览 1.1.1、布局 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-au…

burp靶场--CSRF

burp靶场–CSRF https://portswigger.net/web-security/csrf#what-is-csrf ### 什么是 CSRF&#xff1f; 跨站请求伪造&#xff08;也称为 CSRF&#xff09;是一种 Web 安全漏洞&#xff0c;允许攻击者诱导用户执行他们不打算执行的操作。它允许攻击者部分规避同源策略&#…

Unity 解决异步分发方案

很多程序&#xff0c;包括游戏、小程序、一些AR、VR的程序&#xff0c;因为客户端体量太大&#xff0c;更新频繁都涉及到远程热更新的问题&#xff0c;解决这类问题的思路基本上是客户端解决主要功能&#xff0c;资源类放置在服务器。 下面记录下&#xff1a; 1.CDN或者云轻量…

Windows11操作系统百科

简介 Windows 11是由微软公司&#xff08;Microsoft&#xff09;开发的操作系统&#xff0c;应用于计算机和平板电脑等设备 [1]。于2021年6月24日发布 [3]&#xff0c;2021年10月5日发行 [29]。 Windows 11提供了许多创新功能&#xff0c;增加了新版开始菜单和输入逻辑等 [6]…

安装ddddocr中遇到的问题

1、需要先安装&#xff1a; pip3 install pyinstaller --no-use-pep517 pip install scikit-build pip install setuptools pip install pyinstaller pip install pillow 重要是的是保证一个python 环境&#xff0c;多个python环境会导致各种问题。并且保证python>3.8…

安装宝塔面板后k8s所在节点pod无法正常工作解决方法,kubernetes k8s 与宝塔面板冲突解决方法

在实际项目过程中我们使用了k8s 在生产环境中运行管理服务。 但是对服务器的状态管理我们使用了宝塔面板进行 K8s 版本1.2.8 宝塔面板 版本 8.05 操作步骤是这样的。 1.完成1.2.8 k8s的节点安装&#xff0c;并正常运行服务。 过程略 2.安装宝塔面板 ​ yum install -y …

基于springboot留守儿童爱心网站源码和论文

随着留守儿童爱心管理的不断发展&#xff0c;留守儿童爱心网站在现实生活中的使用和普及&#xff0c;留守儿童爱心管理成为近年内出现的一个热门话题&#xff0c;并且能够成为大众广为认可和接受的行为和选择。设计留守儿童爱心网站的目的就是借助计算机让复杂的管理操作变简单…

Docker的Cgroup资源限制

目录 前瞻 CPU 资源控制 设置CPU使用率上限 设置CPU资源占用比&#xff08;设置多个容器时才有效&#xff09; 设置容器绑定指定的CPU 内存资源限制 对磁盘IO配额控制&#xff08;blkio&#xff09;的限制 前瞻 Docker 通过 Cgroup 来控制容器使用的资源配额&#xff0c…

让抖音引流到微信小程序的三方工具数灵通

抖音作为一款火爆的短视频社交平台&#xff0c;吸引了数亿用户的关注和喜爱。除了观看和制作视频外&#xff0c;抖音还提供了跳转到小程序的功能&#xff0c;让用户可以享受更多功能和乐趣。那么&#xff0c;如何在抖音中跳转到小程序呢&#xff1f;以下是详细解答&#xff1a;…