一、容器deque结构
是双向开口的空间。
而vector是单向的,已知vector的内存扩充是二倍成长。那么deque怎么扩充呢?
双向扩充!
deque的方式是使用分段,然后将各段串接在一起。
map是个vector,其中每个元素是指针,指向每个分段,以将每个分段串接在一起。因此map是个T**类型
如果队列末尾满了,需要再分配一个buffer,并且在map后面中存入指向他的指针。
deque的迭代器iterator是一个class,内部有四个成员:cur,first,last,node
- node:指向控制中心map,迭代器可以知道控制中心在哪,当迭代器需要++或者–的时候,就能通过它回到控制中心以跳到另一个分段。
- last:某个buffer的尾(标识缓冲区的边界)
- first:某个buffer的头(标识缓冲区的边界)
- cur:迭代器的任务是指向某一个元素,cur是在某个缓冲区中迭代器指向的元素。
只有cur才会变动。
当跳到下一个缓冲区buffer,这四个成员都会发生变动。
- start:begin(),返回这个成员
- finish:end(),返回这个成员
template <class T,class Ref,class Ptr,size_t BufSize>
struct __deque_iterator
{
T* cur;
T* first;
T* last;
map_pointer node;//T**
}
template <class T,class Alloc=alloc,size_t BufSize=0>
class deque{
//所谓buffer size是指每个buffer容纳的元素个数
public:
typedef T value_tyep;
typedef __deque_iterator<T,T&,T*,BufSiz> iterator;
protected:
typedef pointer* map_pointer;//T**
protected:
iterator start;//16字节
iterator finish;//16字节
map_pointer map;//4字节
size_type map_size;//4字节
//16*2+4*2=32+8=40字节 一个deque创建出来40字节
public:
iterator begin(){return start;}
iterator end(){return finish;}
size_type size()const {return finish-start;}
...
};
//如果n不为0,传回n,表示buffer size由使用者自定
//如果n为0,表示buffer size使用预设值,那么
//如果sz (sizeof(value_type))小于512,传回512/sz
//如果sz不小于512,传回1
inline size_t __deque_buf_size(size_t n,size_t sz)
{
return n!=0?n:(sz<512?size_t(512/sz):size_t(1));
}
deque的insert函数
由于deque的特殊结构,在插入的时候会进行判断,是往前推还是往后腿,因为deque是双向的。
如果10000个元素,在第4个位置插入,那么前3个元素往前推一个位置。
deque如何模拟连续空间?