不同的库可能会按不同的方式来实现双端队列,通常实现为某种形式的动态数组。但不管通过哪种方式,双端队列都允许通过随机迭代器直接访问各个元素,且内部的存储空间会按需求自动地扩展或收缩。
容器实际分配的内存数超过容纳当前所有有效元素所需的,因为额外的内存将被未来增长的部分所使用。就因为这点,当插入元素时,容器不需要太频繁地分配内存。
因此,双端队列提供了类似向量(std::vector
)的功能,且不仅可以在容器末尾,还可以在容器开头高效地插入或删除元素。
A deque is especially optimized for pushing and popping elements at the beginning and end.
C++编程语言国际标准:ISO/IEC 14882:2011
但是,相比向量,双端队列不保证内部的元素是按连续的存储空间存储的,因此,不允许对指针直接做偏移操作来直接访问元素。
在内部,双端队列与向量的工作方式完全不同:向量使用单数组数据结构,在元素增加的过程中,需要偶尔的内存重分配,而双端队列中的元素被零散地保存在不同的存储块中,容器内部会保存一些必要的数据使得可以以恒定时间及一个统一的顺序接口直接访问任意元素。因此,双端队列的内部实现比向量的稍稍复杂一点,但这也使得它在一些特定环境下可以更高效地增长,特别是对于非常长的序列,内存重分配的代价是及其高昂的。
对于大量涉及在除了起始或末尾以外的其它任意位置插入或删除元素的操作,相比列表(std::list
)及正向列表(std::forward_list
),deque
所表现出的性能是极差的,且操作前后的迭代器、引用的一致性较低。