简介

deque是double ended queue(即双端队列)的简称。 就像C++中的大部分容器的一样,deque具有以下属性:

  • 顺序的(sequence)
  • 动态增长的(dynamic growing)
  • 自定义内存分配的(allocator-aware)

动态内存分配

容器的顺序性(或序列性)和内存分配器我们留到以后再说,这里我们先来探讨下容器的动态增长需求所带来的动态内存分配性质。

动态内存分配在这里的意思是容器的大小会随着需要而增长,这经常伴随着一些内存需求性的操作而发生(例如insert操作,插入一个元素势必需要为这个元素预留内存空间,不然它会成为一个无处息身的流浪狗-^-)。 每个容器都有其实际上的容量(capacity),当容量耗尽,没有多余的空间时,就需要为这个容器动态地增长(正方形单元表示内存单元,深色表示已使用,白色表示未使用):

之所以称之为动态,是因为这个操作发生在运行时。

扩大因子

这里就涉及到resize factor, 也就是重新分配内存时应该分配的内存大小问题。 分配因子太小很可能会造成后续频繁的内存分配需求,因为当前剩下的内存太少;太大又可能造成内存浪费(尤其是当原内存本身就很大时)

sgi stl的扩大因子好像是2(即新的内存大小是原内存的2倍),但有研究指出值为1.5的factor在实际中似乎拥有更好的效果。

实现

在实现上,容器内存的动态增长本质上由以下几步完成:

  1. 分配一块更大的内存空间
  2. 释放之前的内存(在完成内容复制之后)
  3. 替换为新的内存空间

解决的问题

用过C语言的人都知道,C代码中充斥着各种各样的静态内存分配,大部分都以数组的形式出现:

char buffer[1024] = {0};

然而,使用静态内存会带来很多问题:

  • 第一,硬编码,降低了代码的可读性, 看的人根本不知道1024意味着什么。 还好,1024还算是比较典型的数字。但如果换成23、33这些数字,天啊,我完全不知道这些数字是不是有着特殊的含义(你还真别说,有些奇怪的数字还真是特殊考虑过的)!嗯,我们戏称这些数字为魔数(magic number)。
  • 第二,内存利用率。 你分配了很大一块内存,但实际上只使用了很小的一部分。什么?为什么不分配的小一点?哈哈,因为我也不知道到底要分配多大。
  • 第三,静态内存不可增长。 当你知道之前定义的内存大小根本不够用的时候怎么办呢?哦,我可以再定义一个足够大的内存或者把之前的数组大小改得大一些。 那要是这种情况发生在代码运行时呢?
  • 第四,降低工作效率。 处理以上这些琐碎而简单的问题真是让我操碎了神,更烦人的是到处都是这些问题。

如果有那么一种机制,让我在调用各种插入、串接操作时都不用考虑这些问题就好了。 不用想了,那就是动态内存分配!! 动态内存分配的重要性对于C++来说,就像是Garbage Collector对于Java那样重要!

双端队列

好了,言归正传。 实际上,deque想要实现的是一种概念----双端队列。 它是一种LIFO (last in first out)队列,具有以下特性:

  • 双端,即头端和尾端
  • 每个端口都支持入队出队操作

双端

双端分别是头端和尾端,在deque类中对应frontback字样。 带有这两个字样的操作,也即成员函数,都是与端口相关的。

至于为什么采用这两个名称,而不采用诸如headPort、tailPort这样的,我猜想是为了保持各个容器接口之间的一致性与简洁性, 便于记忆。 因为有很多容器都具有 第一个 元素和 最后一个 元素这两个通用概念,front和back刚好对应了它们。 同时,front和back也在一定程度上反映了容器的方向与位置信息,适合用来投射概念上的东西(例如双向链表和双端队列)。

入队和出队

入队、出队操作分别为带有push、pop操作,道理与双端概念大致相似,这里不再赘述。

但这两个操作非常重要的一点就是----不管是在头端还是尾端,时间复杂度都是O(1),即常数时间。

双端队列接口

  • push_back
  • push_front
  • pop_back
  • pop_front

其他接口

理论与实践总是会有不小的距离,容器在实际使用中的易用性有时候更重要。 所以deque类提供的接口远远不止理论上的那几个, 还包括普遍出现在其它容器中的一些接口。 例如Iterator系列、插入、swap、clear等。

C++ 头文件系列(deque)的更多相关文章

  1. C++ 头文件系列(array)

    注意,该头文件仅在C++11中标准才开始出现. 简介 与语言内置的数组一样, array类模版支持几乎所有内置数组包含的特性: 顺序的(sequence) 内存连续的(contiguous stora ...

  2. C++ 头文件系列(queue)

    简介 这个头文件定义了两个跟队列有关的类----quque.priority_queue,分别实现的是队列 和 优先队列这两个概念. 但是与这两个类模版与其它类模版(vector.array等)最大的 ...

  3. C++ 头文件系列(stack)

    简介 该头文件只含有一个类模版stack, 它实现栈的概念,是一个容器适配器(说实话,在写这篇随笔之前我都不知道有这么个类模版). 栈 栈只有一个重要的特性: LIFO(last-in first-o ...

  4. C++ 头文件系列(vector)

    简介 vector头文件包含vector的类模版以及该模版的显示特化版本vector< bool >. vector是C++容器库中非常通用的一种容器,如果你不知道该决定使用哪一种容器,或 ...

  5. C++ 头文件系列(map)

    简介 该头文件包含两个概念相似的容器----map.multimap. 而这两个容器反映的概念就是 映射. 这两个容器 相同 的属性有: 关联性 映射 动态增长 键(Key)唯一性 这两个不相同的属性 ...

  6. C++ 头文件系列(unordered_map、unordered_set)

    简介 很明显,这两个头文件分别是map.set头文件对应的unordered版本. 所以它们有一个重要的性质就是: 乱序 如何乱序 这个unorder暗示着,这两个头文件中类的底层实现----Hash ...

  7. C++ 头文件系列(iterator)

    简介 该头文件围绕迭代器展开,定义了一系列与迭代器有关的概念,但最最最重要的一点就是----它和其它容器一起实现了C++容器的Iterator设计模式. Iterators are a general ...

  8. C++ 头文件系列 (algorithm)

    简介 algorithm头文件是C++的标准算法库,它主要应用在容器上. 因为所有的算法都是通过迭代器进行操作的,所以算法的运算实际上是和具体的数据结构相分离的 ,也就是说,具有低耦合性. 因此,任何 ...

  9. C++ 头文件系列 (bitset)

    简介 该头文件有关位集,实际上是vector 位 位本质上对应bool的概念,只有0或1,true或false两种对立的值. 但很可惜,字节才是机器上最小的存储单元,所以bool基本上是由一个字节大小 ...

随机推荐

  1. SQL点滴10—使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比

    原文:SQL点滴10-使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比 今天偶尔看到sql中也有with关键字,好歹也写了几年的sql语句,居然第一次接触,无知啊.看了一位博主的文章 ...

  2. 【转】NuGet的安装与使用

    学习了一段时间的MVC,今天想自己尝试初步搭建一个MVC框架,结果新建MVC4.0(MVC3.0同样)项目时,弹出一个错误提示框,如下图.上网一搜,说是要安装一个第三方组件NuGet.刚接触MVC,更 ...

  3. 四种方案:将OpenStack私有云部署到Hadoop MapReduce环境中

    摘要:OpenStack与Hadoop被誉为继Linux之后最有可能获得巨大成功的开源项目.这二者如何结合成为更猛的新方案?业内给出两种答案:Hadoop跑在OpenStack上或OpenStack部 ...

  4. leetcode[50] N-Queens

    题目:给定一个n,那么在n*n的棋盘里面放国际象棋的皇后,皇后之间互不在攻击范围.(皇后的攻击范围是她所在位置的哪一行,那一列,和她的正负1的对角线) The n-queens puzzle is t ...

  5. 设置Cookie,登录记住用户登录信息,获取用户登录过得信息

    function setCookie(name,value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getTime() + Da ...

  6. [tarjan] hdu 3836 Equivalent Sets

    主题链接: http://acm.hdu.edu.cn/showproblem.php? pid=3836 Equivalent Sets Time Limit: 12000/4000 MS (Jav ...

  7. sql 将datetime类型转化为指定格式的字符串

    ), ) -- 输出: 05 16 2006 10:57AM ), ) -- 输出: 05/16/06 ), ) -- 输出: 06.05.16 ), ) -- 输出: 16/05/06 ), ) - ...

  8. 干净的架构The Clean Architecture

    干净的架构The Clean Architecture 这是著名软件大师Bob大叔提出的一种架构,也是当前各种语言开发架构.干净架构提出了一种单向依赖关系,从而从逻辑上形成一种向上的抽象系统. 我们经 ...

  9. WCF总结笔记

    ------------------------windowform承载服务步骤: (1)定义契约: using System; using System.Collections.Generic; u ...

  10. error: C1083: 无法打开包括文件:“QDomDocument”“QAxObject”

    包含了头文件但是提示无法打开包括文件,是需要在项目的.pro里面手动加上一个变量 针对QAxObject是 QT       += axcontainer 针对QDomDocument是 QT     ...