简介

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. CSS3 Media Queries 详细介绍与使用方法

    Media Queries 就是要在支援CSS3 的浏览器中才能正常工作,IE8 以下不支持. 而Media Queries 的套用方法千变万化,要套用在什么样的装置中,都可以自己来定义. 到底什么是 ...

  2. 基于NHibernate二级缓存的MongoDB组件

    设计一套基于NHibernate二级缓存的MongoDB组件(上)   摘要:NHibernate Contrib 支持很多第三方的二级缓存,如SysCache,MemCache,Prevalence ...

  3. js 模拟QQ聊天窗口图片播放效果(带滚轮缩放)

    页面效果如下: 完整代码如下: <!DOCTYPE html> <html> <head> <title>Test</title> < ...

  4. Ubuntu12.04环境搭建遇到的问题和建议(一个)

    后的新公司需要在Ubuntu12.04在结构Android开发环境,在这个过程中,我们还是会遇到很多问题,这里记录.为了方便自己的未来,有人谁需要参考.从网络! 1. Q:在终端: sudo apt- ...

  5. Android-异步图像装载机

    在ListView加载图像是非常常见的场景,图像加载几个要求满足以下的: (1)是否画面位于网络或本地上,装载不应同步.但应该异步加载,例如,使用AsyncTask. (2)为了避免重复下载图片和网页 ...

  6. orcale复制表结构及其数据

    http://hi.baidu.com/tag/Oracle/feeds http://hi.baidu.com/gqftuisidibabiq/item/14d306cc87cbdf45bcef69 ...

  7. idea中ajax中文乱码

    case:@RequestMapping中添加 produces= "text/plain;charset=UTF-8", @RequestMapping(method = Req ...

  8. [QT Creator]LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 。

    这个问题很恶心!网上说的原因是因为安装了多了版本的VS.在高版本的2010和2012上都会有问题,解决方法是使用visual studio 2008安装目录下的一个文件替代vs2010安装目录下的文件 ...

  9. 【分享】改变未来的九大算法[pdf][清晰扫描版]

    [下载地址]http://www.colafile.com/file/1179688 图书信息:中文名: 改变未来的九大算法作者: 约翰·麦考密克译者: 管策图书分类: 软件资源格式: PDF版本: ...

  10. TeamCity vs Jenkins: Which is the Better Continuous Integration (CI) Server for .NET Software Development?

    原文:http://www.excella.com/insights/teamcity-vs-jenkins-better-continuous-integration-server So, you’ ...