首先看看deque的模板声明:

template <class T,  class Alloc = allocator<T>>  // 原本还有个参数BufSize,现在新版本内置了,不允许用户指定了。

class deque {
//…
protected:  // 数据成员
    iterator start;        // 表现第一个节点
    iterator finish;       // 表现最后一个节点
    map_pointer map;       // 指向map, map是块连续空间,其内的每个元素都是一个指//针,指向一块缓冲区(Buffer)
    size_type map_size;    // map内可容纳多少指针
    ……
};

vector是单向开口的连续性空间,deque则是一种双向开口的连续性空间(逻辑上)。所谓双向开口,意思是可以在头尾两端分别做元素的插入(常数阶)与删除(常数阶)。当然vector也可以,但其头部操作效率太差(线性阶),无法被接受。

为什么说它只是逻辑上为连续性空间呢?原因在于deque其实是将一段段的连续空间串联起来,而给人造成连续空间的假象,为了这一现象其迭代器真是费了不少功夫呢。

deque接受2个(之前版本为3个)模板参数,其中后者(之前版本为后2个)属于默认参数,一般的话只需写入元素类型即可,如:

deque<int>  deq;

那么那个BufSize参数(之前版本,我们还是了解下)是用来做什么的呢?我们先来看看deque的构造方式。

如图所示,deque采用一块所谓的map作为主控。map是一小块连续空间,其中每个元素都是指针,指向另外一段较大的连续线性空间,称为缓冲区。缓冲区才是deque的存储空间主体。

deque <int, allocator<int>>  deq;

(图片来自侯捷老师课程《STL与泛型编程》, 侵删)

  deque内设2个迭代器,如上图所示分别为start和finish,每个迭代器拥有4个指针,分别为cur, first, last, node.像start的cur指向容器首元素,first指向该元素位于的缓冲区的头,last指向该元素位于的缓冲区的尾。通过指针node控制map的前进后退。当map使用率满载时,再找一个更大的空间来作为map,map又来控制缓冲区,如此而已。当然构造出连续空间的假象,迭代器的实现就比较麻烦了,这里就不介绍了,我们只做了解。

简单对deque的结构了解后,我们来写一段测试代码:

#include <deque>
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    deque<,);
    cout << "size = " << ideq.size() << endl;          // size = 20(20个元素,都为9) 

    // 为每一个元素设置新值
    ; i < ideq.size(); i++) {
        ideq[i] = i;
    } 

    ; i < ideq.size(); i++) {            // 0 1 2 3 ...19
        cout << ideq[i] << " ";
    }
    cout << endl;

    ; i < ; i++) {
        ideq.push_back(i);
    }

    ; i < ideq.size(); i++) {            // 0 1 2 3 ...19 0 1 2
        cout << ideq[i] << " ";
    }
    cout << "size = " << ideq.size() << endl;          // size = 23

    ideq.push_front();
    ; i < ideq.size(); i++) {            // 99 0 1 2 3 ...19 0 1 2
        cout << ideq[i] << " ";
    }
    cout << "size = " << ideq.size() << endl;          // size = 24

    deque<int, allocator<int>>::iterator iter;
    iter = find(ideq.begin(), ideq.end(),);

    ;
 } 

  当然随着编译器的版本的更新,内部细节会发生一些变化,比如新版本取消了让用户自定义buffersize,转为内部自行实现。但基本原理及其存储方式是不会变化的。况且deque容器之复杂,也不是可以用这么短的文字和代码说明的,这里只是介绍deque的基本存储结构和运用,如果有兴趣加深加深了解的话推荐《STL源码剖析》,同时也推荐直接打开系统头文件自行阅读。

STL之序列容器deque的更多相关文章

  1. STL之顺序容器 deque 动态数组

    deque是一个动态数组,deque与vector非常类似,vector是一个单向开口的连续线性空间,deque则是双向开口的连续线性空间.两者唯一的区别是deque可以在数组的开头和末尾插入和删除数 ...

  2. STL常用序列容器

    这里简要的记述一下STL常用容器的实现原理,要点等内容. vector vector是比较常用的stl容器,用法与数组是非类似,其内部实现是连续空间分配,与数组的不同之处在于可弹性增加空间,而arra ...

  3. STL之序列容器vector

    首先来看看vector的模板声明: template <class T, class Alloc = allocator<T>> class vector { //… }; v ...

  4. STL标准库-容器-deque

    技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性. deque双向开口可进可出的容器 我们知道连续内存的容器不能随意扩充,因为这样容易扩充别人那去 deque却可以,它创造了内存 ...

  5. STL标准库-容器-deque 双端队列

    头文件: #include<deque> 常用操作: https://www.cnblogs.com/LearningTheLoad/p/7450948.html

  6. C++——STL之vector, list, deque容器对比与常用函数

    STL 三种顺序容器的特性对比: vector 可变数组,内存空间是连续的,容量不会进行缩减.支持高效随机存取,即支持[]和at()操作.尾部插入删除效率高,其他位置插删效率较低: list 双向链表 ...

  7. 《STL源码剖析》——第四章、序列容器

     1.容器的概观与分类 所谓序列式容器,其中的元素都可序(ordered)[比如可以使用sort进行排序],但未必有序(sorted).C++语言本身提供了一个序列式容器array,STL另外再提供v ...

  8. C++ STL之list容器的基本操作

    由于list和vector同属于序列式容器,有很多相同的地方,而上一篇中已经写了vector,所以这一篇着重写list和vector的不同之处和特有之处. 特别注意的地方: (1)STL中迭代器容器中 ...

  9. ###STL学习--关联容器

    点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的关联容器. ###stl学习 |--迭 ...

随机推荐

  1. php捕捉来自搜索引擎的用户IP地址时间和访问路径

    刚才看demo看到很有意思的地方记录一下 $zz_page=$_SERVER['REQUEST_URI']; $zz_name=$_SERVER['HTTP_USER_AGENT']; $zz_ip= ...

  2. Servlet中The requested resource is not available错误

    自己为了测试servlet,用MyEclipse2015写了一个简单的登录程序. 1.登录页面index.jsp. <%@ page language="java" impo ...

  3. 原生js发送ajax请求

    堕落了一阵子了,今天打开博客,发现连登录的用户名和密码都不记得了.2016年已过半,不能再这么晃荡下去了. 参加了网易微专业-前端攻城狮 培训,目前进行到大作业开发阶段,感觉举步维艰.但是无论如何,不 ...

  4. C语言字符串操作总结大全(超详细)

    本篇文章是对C语言字符串操作进行了详细的总结分析,需要的朋友参考下 1)字符串操作  strcpy(p, p1) 复制字符串  strncpy(p, p1, n) 复制指定长度字符串  strcat( ...

  5. photoshop,黑白转彩色单色

    方法一: 打开 色相/饱和度 面板,勾选上 着色, 然后调节 明度 滑块. 方法二: 前面方法的缺点是会将修改直接塌陷到图层,如果想不塌陷,可以使用色相蒙板: 同样勾选 着色

  6. Centos6---Fail2ban

    1.安装: rpm -ivh http://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm yum -y install ...

  7. 阿里云centos yum源更换,两个文件是从阿里云服务器拷贝出来的,可安装openvpn

    第一步:备份你的原镜像文件,以免出错后可以恢复. mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.back ...

  8. Tomcat启动脚本

    记录一个比较好的tomcat启动脚本,截取<OneinStack>,修改如下两个参数即可用. 使用之前修改下面2个参数: #Location of JAVA_HOME (bin files ...

  9. centos nginx server_name 配置域名访问规则

    今天配置Server_name时,希望禁用一些域名,应为这些域名我想让通过另外一个Server配置 server_name "~^((\w*[^w]{1}\w*)|w{1,2})\.hell ...

  10. WPF中的image控件的Source赋值

    WPF中的Image控件Source的设置 1.XAML中 简单的方式(Source="haha.png"); image控件的Source设置为相对路径后(Source=&quo ...