一:特点
双端队列 double-end queue
deque是在功能上合并了vector和list。
优点:
(1) 随机访问方便,即支持[ ]操作符和vector.at()
(2) 在内部方便的进行插入和删除操作
(3) 可在两端进行push、pop
缺点:
(1) 占用内存多
使用区别:
1 如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2 如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3 如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque
二:deque的内存分布
deque是逻辑上连续的地址空间,只是逻辑上的,并不向vector那样物理上就是连续的地址空间,严格的来说,deque的内存是一序列不连续的段组成,但是每个段都是物理上连续的地址。掌控这些段的中心是一个Map(这并不是stl中的map容器),它也是一个连续的空间,每个元素都是一个指针,它指向的位置就是每个段(缓冲区)。
template<class T.....>
class deque
{
typedef T value_type;
typedef value_type* pointer;
.
.
.
typedef _deque_iterator<T....> iterator;
typedef pointer* map_pointer;
.
.
.
iterator start;//第一个节点
iterator finish;//最后一个节点
map_pointer map;//中控器
}
deque和vector的内存分配相似,但是他们的迭代器一点也不相同。记得vector的迭代器就是一个指针。而deque的迭代器并不这么简单。
只写出它的一部分结构:
template<class T....> struct _dequeue_iterator { . . typedef T** map_pointer; . . T* cur; //该node的当前位置 T* first;//该node的开始位置 T* last;//该node的结束位置 map_pointer node;//指向的中控器map的一个节点 . . . }
以上都是理论知识。让我们开始用一个例子来分析它吧。
deque<int,alloc,32>ideq(20,9)
这样就构造了一个deque,有20个int元素,每个元素为9。缓冲区为32个字节。(默认为0),alloc为空间分配器。在其中其实做了很多
初始化size,start,finish iterator(指明它们在哪个节点和cur当前位置)
size_type num_nodes=num_elements/buffer_size()+1; map_size=max(initial_map_size,num_nodes+2); map=map_allocator:;allocate(map_size); map_pointer nstart=map+(map_size-num_nodes)/2; map_pointer nfinish=nstart+num_nodes-1; start.set_node(nstart) finish.set_node(nfinish) start.cur=start.first; finish.cur=finish.first+num_elements%buffer_size();
pop_back push_back pop_front push_front
push_front:
当执行在前面插入元素后,首先看start.cur和start.first的相对位置,如果start.cur=start.first,那么start节点没有空余空间,此时就需要再分配一段空间,并且在map中再添加一个节点,start指向该节点,同时还要更新start迭代器的每个元素(first,end,cur,node)。
start.set_node(start.node-1);
start.cur=start.last-1;
push_front(99)之后
因为start节点没有空余空间,所以就重新分配一段连续内存空间。
其他的也是同样的分析。。