一.定义
<1>Double ended queue(双端队列)
deque (usually pronounced like "deck") is an irregular acronym(首字母缩略词)of double-ended queue. Double-ended queues are sequence containers with dynamic sizes that can be expanded or contracted on both ends (either its front or its back).
deque(通常读作“德克”)是一种对双端队列不规则的首字母缩写。双向队列是一种具有动态尺寸能够在前后端扩大及缩小特性的线性容器
Specific libraries may implement deques in different ways, generally as some form of dynamic array. But in any case, they allow for the individual elements to be accessed directly through random access iterators, with storage handled automatically by expanding and contracting the container as needed.
特定库可能以不同的方式实现双端队列,通常是某种形式的动态数组。但是无论怎样,它们都允许直接通过随机访问迭代器对单个元素进行访问,能够按照需要自动扩大或者缩小存储空间
Therefore, they provide a functionality similar to vectors, but with efficient insertion and deletion of elements also at the beginning of the sequence, and not only at its end. But, unlike vectors, deques are not guaranteed to store all its elements in contiguous storage locations: accessing elements in a deque
by offsetting a pointer to another element causes undefined behavior.
因此,它们提供与vector相似的功能,但在序列的开头也有效插入和删除元素,而不仅仅是在其结尾。但是,与vectors不同,deques 不能保证存储的所有元素都在连续的内存中:通过偏移指针的方式访问元素可能会造成不明确的行为
模拟deque在内存中的分布(块内连续,块间不连续)
每当迭代器处于一块内存的末尾时将由operator++跳到下一块内存,因此支持迭代器自增操作
Both vectors and deques provide a very similar interface and can be used for similar purposes, but internally both work in quite different ways: While vectors use a single array that needs to be occasionally reallocated for growth, the elements of a deque can be scattered in different chunks of storage, with the container keeping the necessary information internally to provide direct access to any of its elements in constant time and with a uniform sequential interface (through iterators). Therefore, deques are a little more complex internally than vectors, but this allows them to grow more efficiently under certain circumstances, especially with very long sequences, where reallocations become more expensive.
vectors 和 deques 都提供非常相似的接口同时可用于类似的目的,但是两者在内部工作上却有极大的不同:vectors 使用一个数组,增长时偶尔需要重新分配(此块内存不足以存储新增数据),然而deques的元素能够分散在不同块的内存中,容器保存必要的内部信息用以在常数阶时间和顺序的接口(通过迭代器)访问元素。因此,deques在内部实现上比vectors更复杂,但是这也让它们(指deques)在特定环境下增长更具效率,尤其是对于非常长的序列时,这种时候重新分配代价高昂。
For operations that involve frequent insertion or removals of elements at positions other than the beginning or the end, deques perform worse and have less consistent iterators and references than lists and forward_lists.
对于涉及在开头或结尾以外的位置频繁插入或删除元素的操作,deques表现更差(效率低,时间复杂度高,动态数组也是顺序存储,中间插入需要移动元素),并且与 lists 和 forward_lists 相比具有更少连续的迭代器和引用(因为deques中的并非所有元素都是内存连续的,因此其迭代器也并非全部连续,之所以支持迭代器自增操作关键在于容器内部operator实现了块间内存的跳跃)。
<2>声明方式:
(1).deque<type> name;
(2).deque<type> name = {e1,e2,e3,....}
二.主要操作
<1>增加元素:
(1).从后端增加:push_front(T element)
(2).从前端增加:push_back(T element)
(3).中间插入: name.insert( name.begin()+n, T element);
<2>删除元素:
(1).从前端删除:pop_front()
(2).从后端删除:pop_back()
(3).中间删除: name.erase(name.begin()+n)
(4).清空deque: name.clear()
<3>.迭代器
(1).声明:deque<T>::iterator e;
(2)使用:for(e = name.begin() ; e!=name.end() ; e++) *e(注意:迭代器是一个指针)
(3)利用distance(begin,end):计算begin到end的距离可用于计算当前元素在deque中的下标
<4>.有关内存
(1).元素个数:name.size()
(2).判断是否为空:name.empty()
(3).最大容量:name.max_size()
(4).改变deque的大小:name.resize(size_type n,value_type t ):
size_typye:
如果n小于当前容器大小,则内容将减少为前n个元素,删除超出(并销毁它们)的元素。如果n大于当前容器大小,则通过在末尾插入尽可能多的元素来扩展内容以达到n的大小。如果指定了val,则新元素将初始化为val的副本,否则,它们将进行值初始化。
value_type t:
在n大于当前容器大小的情况下将其内容复制到添加元素的对象。
如果未指定,则使用默认构造函数。
成员类型value_type是容器中元素的类型,在deque中定义为第一个模板参数(T)的别名。
三.代码
#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;
int main() {
//assign a int_deque called a
deque<int> a;
//add elements to a by the function: push_back()
for(int i = 0 ; i<10 ; i++)
a.push_back(i);
//a.push_front(-1);
//output deque_a by for_circle
for(size_t i = 0 ; i<10 ; i++)//size_t is equally int in 32bite os and long in 64bite os.
cout<<a[i]<<" ";
cout<<endl;
//delete the last element
a.pop_back();
//delete the first element
a.pop_front();
//output deque_a by iterator
//assign an iterator e
deque<int>::iterator e;
for(e = a.begin() ; e!=a.end() ; e++)
{
//get the elements' index by the function: distance()
int index = distance(a.begin(),e);
cout<<"a["<<index<<"]"<<*e<<" ";
}
return 0;
}