百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

C++标准容器类第1节,支持首尾插入,双端队列deque使用实例详解

bigegpt 2025-05-02 16:44 13 浏览

C++中的标准容器 deque(发音像 deck) 是双端队列(double-ended queue)的缩写,本质上是队列容器,修饰词“双端”说明它可以在两端进行扩展或者收缩。

deque 容器类的特点

就单单 deque 来说,它的实现方式有很多种,其用途也会因实现方式的差异略有不同。不过,C++通常是将其作为某种形式的动态数组,对于 C++中的 deque,我们可以通过迭代器直接访问 deque 容器中存储的各个元素,并且根据需要在其两端进行任意的扩展和收缩。

C++中 deque 容器提供的功能有些类似于向量(vector,后面会说),但是 deque 既支持将元素插入容器的头部,也支持将元素插入容器的尾部,而向量容器则只能将新元素插入尾部,请看下面这几行C++代码:

#include 
#include 
using namespace std;
int main()
{
 vector v;
 deque d;
 d.push_back(1);
 d.push_front(2);
 v.push_back(1);
 v.push_front(2); // 非法
 return 0;
}

另外需要说明的是,deque 容器不能保证内部元素存储在相邻的位置,也就是说 deque 容器内的元素在内存中的地址可能不是连续的,这一点和普通的链表相似——链表中的各个节点常常并不在内存中连续分布。因此,deque 容器不能提供高效的随机访问。

C++ 中的 deque 容器类与向量 vector 容器类的接口非常相似,但是二者在内部的工作方式截然不同。vector 内部使用类似于数组的一整块连续内存,因此它可以高效的随机访问各个元素。但是,一旦添加的元素超出预先分配的内存长度,那么 vector 将不得不重新分配一块更大的连续内存,并将现有数据拷贝到该新连续内存段,再执行接下来的添加操作。

deque 就不同了,它内部的元素并不需要在地址上相邻,因此各个元素可以分散在不同的存储块中,容器内部保留必要的信息,以便能够在恒定时间内按照统一的顺序访问任何元素。deque 内部管理元素的方式比 vector 复杂一些,但是着允许它在某些情况下更有效的增长,特别适合处理非常长的序列。

deque 容器类的成员函数及其实例

我不打算详细介绍和讨论枯燥的函数原型及其说明,相关资料科自行查阅文档,这里仅通过实例直观的介绍各个成员函数的使用。

deque 的迭代器

deque 是一个容器类,其中可以存放若干个元素,若要逐个访问其中的元素,则可以通过迭代器函数,其中最常用的有以下几个函数:

以下是付费内容

  • begin,返回迭代器的起点
  • end,返回迭代器的终点
  • rbegin,返回反迭代器的反起点
  • rend,返回反迭代器的反终点

下面是使用 begin() 和 end() 函数遍历 deque 容器类元素的 C++ 代码示例,请看:

其实从这里可以看出,所谓的迭代器“it”,其实更像是一个指向 deque 内元素的指针,我们可以通过对其执行自加操作,让它指向下一个元素,以此遍历所有元素。编译并执行上述C++代码,得到如下输出:

mydeque contains: 1 2 3 4 5

可见,mydeque 内部的元素按照插入顺序遍历出来了。当然,我们也可以使用 rbegin() 和 rend() 函数倒序操作 deque 容器,下面是一段C++代码示例,请看:

上述C++代码先使用 rbegin() 和 rend() 函数倒序访问 mydeque 容器元素并赋值,然后顺序遍历打印,最终得到的输出为:

mydeque contains: 5 4 3 2 1

deque 的容量

容器究竟存放多少元素,也是一个非常重要的问题,因此 deque 类提供了下面几个常用的函数用于检查和设置容器的容量:

  • size,返回容量
  • max_size,返回最大容量
  • resize,修改容量
  • empty,检查容器是否为空

size() 函数返回容器内部存放的元素数目,empty() 函数返回容器内是否有元素,这没什么说的。那 max_size() 函数是什么意思呢?它有什么用呢?请看下面这段C++代码示例:

这段C++程序允许用户输入一个整数,并将其中的 mydeque 容器容量设置(resize)为该整数大小。当然了,在设置大小之前,需要检查用户输入的整数是否超出了容器的最大容量。

仔细想想,deque 容器内的各个元素在内存中可以分散分布,因此在内存被使用完毕之前,deque 永远都不会满。也就是说,deque 的 max_size() 是非常大的,这与C++程序运行的机器内存和单个元素大小有关。

感兴趣的读者可以将本例中的 max_size() 的值打印出来,应该能够发现它是一个非常非常大的值。

resize() 函数可以设置 deque 容器的容量,这意味着它既可以压缩 deque 容器,也可以拉伸 deque 容器。若是使用 resize() 函数拉伸了 deque 容器,那么就会多出一部分空间, resize() 函数还可以为这部分多出的空间设置默认值,请看下面这段C++代码示例:

程序首先往 mydeque 容器中添加了 9 个连续的数字,然后使用 resize() 函数将容器容量压缩到 5,接着又将容量拉伸值 8,并且将多出的 3 个位置赋值为 100,最后将 mydeque 容器容量拉伸值 12,因此上述C++程序的最终输出结果为:

mydeque contains: 1 2 3 4 5 100 100 100 0 0 0 0

最后多出的 4 个空闲位置元素为 0,是因为 resize(12) 没有显式的指定初值,因此这几个位置被赋为默认的 0 了。

访问 deque 容器的元素

以下几个函数是 deque 类提供的常用的访问容器内元素的函数,请看:

  • operator[],访问元素
  • at,访问元素
  • front,访问第一个元素
  • back,访问最后一个元素

这几个函数非常简单,相关的C++代码示例如下,请看:

编译并执行这段C++代码示例,得到如下输出:

mydeque[3] = 4
mydeque.at(4) = 5
mydeque.front() = 1
mydeque.back() = 9

deque 的其他函数

为了便于使用,deque 容器类还提供了其他的函数,比较常用的有下面这几个:

  • assign,赋值
  • push_back,将元素添加到容器尾部
  • push_front,将元素添加到容器头部
  • pop_back,删除最后一个元素
  • pop_front,删除第一个元素
  • insert,插入元素
  • erase,擦除元素
  • swap,交换
  • clear,清除

assign() 函数可以实现类似于“拷贝”的操作,也可以实现类似于“resize”的操作,下面是C++代码示例,请看:

若 assign() 函数的第一个参数为整数(n),则表示将该 deque 容器的容量设置为 n,我们也可以在第二个参数为其制定默认值。assign() 也可以通过迭代器将一个 deque 中的元素拷贝给另外一个 deque,例如上面的C++代码,second 容器类拷贝了由 it 索引的 first 容器类中的第二个元素到倒数第二个元素(第一个和最后一个元素没有拷贝,因此 second 容器容量比 first 容器容量小 2)。编译并执行这段C++代码,得到如下输出,请看:

Size of first: 7
Size of second: 5
Size of third: 3

前面的例子中几乎都用到了 push_back() 函数,它可以将元素插入到 deque 的尾部,与之对应的,pop_back() 函数则可以将 deque 尾部的元素删除。下面是C++代码示例,请看:

之所以可以使用 mydeque.empty() 决定 while() 循环条件,是因为C++程序在使用完容器尾部元素之后,调用了 pop_back() 将之删除了。编译并执行这段代码,得到如下输出:

The elements of mydeque add up to 60

push_front() 和 pop_front() 也可使用类似于上面这样的C++代码示例,唯一不同的是它们操作的是容器的头部元素——即 push_front() 将元素插入容器头部,pop_front() 将容器的头部元素删除。

erase() 函数则可以从 deque 容器中擦除指定的元素,究竟擦除哪一个元素则由 erase() 的参数决定,通常 erase() 接收一个迭代器指针。请看下面这段C++代码示例:

从代码中可见,erase() 函数可以接收一个迭代器指针删除单个元素,也可以接收两个迭代器指针表示的区间,删除区间内的元素。编译并执行这段C++代码,得到如下输出:

mydeque contains: 4 5 7 8 9 10

swap() 函数则提供了交换功能,使用它可以交换两个 deque 容器内的内容,下面这段C++代码示例很好的说明了这一点,请看:

编译并执行这段C++代码,得到如下输出,可见 foo 和 bar 容器的内容被交换了:

foo contains: 200 200 200 200 200 
bar contains: 100 100 100 

小结

本文主要通过一系列C++代码示例讨论了标准容器类 deque 的使用,文中的例子都是以 deque 作为示范的,应该明白 deque 本身是一个模版容器类,因此它可以存储任意类型的数据,例如 deque,deque,deque,deque<deque> 等等。</deque

欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。

未经许可,禁止转载。

相关推荐

当Frida来“敲”门(frida是什么)

0x1渗透测试瓶颈目前,碰到越来越多的大客户都会将核心资产业务集中在统一的APP上,或者对自己比较重要的APP,如自己的主业务,办公APP进行加壳,流量加密,投入了很多精力在移动端的防护上。而现在挖...

服务端性能测试实战3-性能测试脚本开发

前言在前面的两篇文章中,我们分别介绍了性能测试的理论知识以及性能测试计划制定,本篇文章将重点介绍性能测试脚本开发。脚本开发将分为两个阶段:阶段一:了解各个接口的入参、出参,使用Python代码模拟前端...

Springboot整合Apache Ftpserver拓展功能及业务讲解(三)

今日分享每天分享技术实战干货,技术在于积累和收藏,希望可以帮助到您,同时也希望获得您的支持和关注。架构开源地址:https://gitee.com/msxyspringboot整合Ftpserver参...

Linux和Windows下:Python Crypto模块安装方式区别

一、Linux环境下:fromCrypto.SignatureimportPKCS1_v1_5如果导包报错:ImportError:Nomodulenamed'Crypt...

Python 3 加密简介(python des加密解密)

Python3的标准库中是没多少用来解决加密的,不过却有用于处理哈希的库。在这里我们会对其进行一个简单的介绍,但重点会放在两个第三方的软件包:PyCrypto和cryptography上,我...

怎样从零开始编译一个魔兽世界开源服务端Windows

第二章:编译和安装我是艾西,上期我们讲述到编译一个魔兽世界开源服务端环境准备,那么今天跟大家聊聊怎么编译和安装我们直接进入正题(上一章没有看到的小伙伴可以点我主页查看)编译服务端:在D盘新建一个文件夹...

附1-Conda部署安装及基本使用(conda安装教程)

Windows环境安装安装介质下载下载地址:https://www.anaconda.com/products/individual安装Anaconda安装时,选择自定义安装,选择自定义安装路径:配置...

如何配置全世界最小的 MySQL 服务器

配置全世界最小的MySQL服务器——如何在一块IntelEdison为控制板上安装一个MySQL服务器。介绍在我最近的一篇博文中,物联网,消息以及MySQL,我展示了如果Partic...

如何使用Github Action来自动化编译PolarDB-PG数据库

随着PolarDB在国产数据库领域荣膺桂冠并持续获得广泛认可,越来越多的学生和技术爱好者开始关注并涉足这款由阿里巴巴集团倾力打造且性能卓越的关系型云原生数据库。有很多同学想要上手尝试,却卡在了编译数据...

面向NDK开发者的Android 7.0变更(ndk android.mk)

订阅Google官方微信公众号:谷歌开发者。与谷歌一起创造未来!受Android平台其他改进的影响,为了方便加载本机代码,AndroidM和N中的动态链接器对编写整洁且跨平台兼容的本机...

信创改造--人大金仓(Kingbase)数据库安装、备份恢复的问题纪要

问题一:在安装KingbaseES时,安装用户对于安装路径需有“读”、“写”、“执行”的权限。在Linux系统中,需要以非root用户执行安装程序,且该用户要有标准的home目录,您可...

OpenSSH 安全漏洞,修补操作一手掌握

1.漏洞概述近日,国家信息安全漏洞库(CNNVD)收到关于OpenSSH安全漏洞(CNNVD-202407-017、CVE-2024-6387)情况的报送。攻击者可以利用该漏洞在无需认证的情况下,通...

Linux:lsof命令详解(linux lsof命令详解)

介绍欢迎来到这篇博客。在这篇博客中,我们将学习Unix/Linux系统上的lsof命令行工具。命令行工具是您使用CLI(命令行界面)而不是GUI(图形用户界面)运行的程序或工具。lsoflsof代表&...

幻隐说固态第一期:固态硬盘接口类别

前排声明所有信息来源于网络收集,如有错误请评论区指出更正。废话不多说,目前固态硬盘接口按速度由慢到快分有这几类:SATA、mSATA、SATAExpress、PCI-E、m.2、u.2。下面我们来...

新品轰炸 影驰SSD多款产品登Computex

分享泡泡网SSD固态硬盘频道6月6日台北电脑展作为全球第二、亚洲最大的3C/IT产业链专业展,吸引了众多IT厂商和全球各地媒体的热烈关注,全球存储新势力—影驰,也积极参与其中,为广大玩家朋友带来了...