1.1. deque
1.2. deque概述
deque双向开口逻辑上的连续空间,且没有容量的概念,即需要多少分配多少。deque的数据结构如下:
图 deque的数据结构概略图
其中,缓冲区才是deque中元素真正的存储地方。map是deque的中控器。
deque中每个缓冲区的大小通常是固定的,其大小的获取函数入下:
inline size_t __deque_buf_size(size_t __size) {
return __size < 512 ? size_t(512 / __size) : size_t(1);
}
函数返回缓冲区中能容纳的元素个数(返回值大于0),__size往往是元素大小(sizeof(value_type))。
1.2.1. deque的迭代器
deque的迭代器主要实现operator++和operator--,主要考虑两个方面:
1) 迭代器移动到缓冲区的边缘的处理;
2) 迭代器访问中控器map。
difference_type operator-(const _Self& x) const {
return difference_type(buffer_size()) * (node - x.node - 1) +
(cur - first) + (x.last - x.cur);
}
两个迭代器间的距离如下图:
图 两个迭代器之间距离
注:两头的备用缓冲区未画
_Self& operator+=(difference_type n)
{
difference_type offset = n + (cur - first); // 相对本缓冲区节点起始位置
if (offset >= 0 && offset < difference_type(buffer_size()))
cur += n;
else {
// 因为buffer_size()的返回值>0,因此执行到这只有两种可能:offset<0和
// offset>0&&offset> difference_type(buffer_size())
difference_type node_offset =
offset > 0 ? offset / difference_type(buffer_size())
: -difference_type((-offset - 1) / buffer_size()) - 1;
set_node(node + node_offset);
cur = first +
(offset - node_offset * difference_type(buffer_size()));
}
return *this;
}
其中-difference_type((-offset - 1) / buffer_size())-1,之所以-1是因为当offset<0时肯定要左移一个缓冲区节点(当前缓冲区节点),(-offset - 1)是避免移过偏移offset所指向的缓冲区节点。如图所示:
图 迭代器移动n