deuqe STL容器深入解析------/deque简述/deque源码简单剖析/deque的数据结构/deque的应用

本文详细介绍了STL deque容器,它是一种双端队列,允许在两端进行插入和删除操作。deque不同于vector,其内部由多个连续空间(缓冲区)组成,通过中配器管理,提供了常数时间的头尾操作。deque的迭代器复杂,负责维持其连续空间的假象。deque在实现栈和队列等数据结构时表现出高效性,但日常编程中使用较少。STL的stack和queue是基于deque实现的适配器,而非独立容器。
摘要由CSDN通过智能技术生成

前言:deque (double-ended queue,双端队列)是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。而在STL中,deque的实现尤为精妙。而理解deque容器,对理解STL、提高C++技术有重要意义
而本文将详细介绍STL的deque容器

1、deque简述

简单定义:deque双端队列,具有动态大小的序列容器,可以在两端(前端或后端)扩展或收缩,是兼具栈(stack)和队列(queue)性质的序列式容器。
生活中的deque:双端队列在现实生活中的例子:一个刚买了票的人如果只是还需要再问一些简单的信息,就可以直接回到队伍的头部。另外,在队伍末尾的人如果赶时间,他可以直接离开队伍。通过双端队列,对相应的问题可以做到较好的模拟.
在这里插入图片描述
——(图片取自网络)

2、deque成员函数一览

在这里插入图片描述
在这里插入图片描述
——(图表取自C语言中文网

3、deque源码简单剖析

1)deque容器与vector容器的差异

在初学STL时,我们常常有一种自然的错觉:deque容器只是前端多开一个口的vector容器而当我们深入学习STL,从源码层面剖析时,我们会发现许多惊奇的差异
而最主要的两点差异在

  1. deque允许 以常数时间O(1) 内对起头端进行元素的插入和移除操作,而 vector头部操作效果奇差————这是最显而易见的不同。
  2. deque没有所谓容量(capacity)的观念,因为它是动态地以分段连续空间组合而成,随时可以增加一段新的空间并链接起来。

关于这第二点,其实从上面的"deque成员函数一览",就初见端倪
熟悉vector容器的朋友很容易发现:
vector容器关于容量操作的函数几乎没在deque中出现
像vector的:
resize() 改变实际元素的个数。
capacity() 返回当前容量。
reserve() 增加容器的容量。

都没有在deque容器的成员函数里出现

在这里插入图片描述
也正因此,deque没有所谓空间保留的
(reserve)函数!!!


第一点倒是好理解,但过于第二点,能再解释一下吗?
——要搞清第二点,我们必须要搞清deque的数据结构。
👇👇👇



2)deque到底是不是连续的

在逻辑上、在实际操作中,deque都可以被视为连续空间。而由此可以类比 同样为线性连续空间的array/vector

  • array不可成长,固定大小,支持快速随机访问,不能添加/删除元素。
  • vector只能向尾端延伸,一但vector容器空间已满,它将 1】开辟新的空间(这个空间大小常常是原来空间的两倍左右)2】将原来的数据拷贝到新空间中 3】释放原有空间。

关于deque容器,它是如何实现增长的呢?

实际上:deque容器由一段一段的定量连续空间(缓冲区)构成。一旦有必要在deque前端或后端增加新空间,便配置一段定量连续空间,串联在整个deque的头端或尾端deque最大的任务,就是在这些分段的定量连续空间上,维护其整体连续的假象,并提供随机存取的接口,避开了vector“重新配置,拷贝,删除”的轮回,但代价则是复杂的迭代器架构和新增中配器的维护。

所以,严格意义上来说,deque容器不是连续的,它是由一段段连续空间串联起来的。不能把deque/vector混为一谈。
也这是这个原因,直接对deque STL sort排序往往十分低效。为提高效率,我们一般讲deque先完整复制一个vector容器身上,将vector用(STL sort 算法)排序后,再拷贝回deque容器
👇👇中配器

3)deque中配器

从上文,我们可以知道deque容器由一段一段的定量连续空间(缓冲区) 构成。
这一片片缓冲区才是deque存储元素的真正位置。而这些缓冲区是零散的,要管理好它们,就必须需要一个中央控制,这也就是我们所说的中配器

deque采用一块所谓的map(注意,不是STL的map容器,这里可以简单地理解为它是帮助程序找到各个缓冲区的地图)作为主控,这里所谓的map是一小块的连续空间,其中的每个元素(此处称为一个节点,node)都是指针,指向缓冲区。

要深入理解map,先看看map的源码

template <class T, class Alloc = alloc, size_t BufSiz = 0>//SGI STL允许我们指定缓冲区大小,默认值0将使用512 bytes缓冲区
class deque{
   
public:                        //基本类型
    typedef T value_type;
    typedef T value_type* pointer;
    ...
protected:                   //Internal typedefs
    //元素的指针的指针(pointer of pointer of T)
    typedef pointer* map_pointer;
p
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0<Solving)1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值