一、定义
deque是两端都可以插入删除的线性表。
图示:
deque与vector的区别:
(1)deque两端都可已插入删除,vector只在尾端插入删除;
(2)deque没有容量的概念,它是由分段连续空间组成的,随时可以增加一个新的空间并连接起来,vector为连续的内存可增长的地址空间。
二、deque数据结构
deque采用一小段的map作为主控,每个元素都是一个指针,指向另一个线性空间(缓冲区),缓冲区才是deque的主体。
template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class deque : protected _Deque_base<_Tp, _Alloc> {
__STL_CLASS_REQUIRES(_Tp, _Assignable);
typedef _Deque_base<_Tp, _Alloc> _Base;
public: //基本类型
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef typename _Base::allocator_type allocator_type;
allocator_type get_allocator() const { return _Base::get_allocator(); }
public: // 迭代器
typedef typename _Base::iterator iterator;
typedef typename _Base::const_iterator const_iterator;
protected:
typedef pointer* _Map_pointer; //map指针
static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }//缓冲区
图示:
三、deque迭代器
template <class _Tp, class _Ref, class _Ptr>
struct _Deque_iterator {
typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }//缓冲区大小
typedef random_access_iterator_tag iterator_category;//类型
typedef _Tp value_type;
typedef _Ptr pointer;
typedef _Ref reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Tp** _Map_pointer;
typedef _Deque_iterator _Self;
_Tp* _M_cur; //缓冲区中现行的元素
_Tp* _M_first; //缓冲区的头
_Tp* _M_last; //缓冲区的尾
_Map_pointer _M_node;//map指针
_Deque_iterator(_Tp* __x, _Map_pointer __y) //构造函数
: _M_cur(__x), _M_first(*__y),
_M_last(*__y + _S_buffer_size()), _M_node(__y) {}
_Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
_Deque_iterator(const iterator& __x)
: _M_cur(__x._M_cur), _M_first(__x._M_first),
_M_last(__x._M_last), _M_node(__x._M_node) {}
reference operator*() const { return *_M_cur; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return _M_cur; }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
difference_type operator-(const _Self& __x) const {
return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
(_M_cur - _M_first) + (__x._M_last - __x._M_cur);
}
_Self& operator++() {//前置++重载
++_M_cur;
if (_M_cur == _M_last) {
_M_set_node(_M_node + 1);
_M_cur = _M_first;
}
return *this;
}
_Self operator++(int) {//后置++重载
_Self __tmp = *this;
++*this;
return __tmp;
}
_Self& operator--() {//前置--重载
if (_M_cur == _M_first) {
_M_set_node(_M_node - 1);
_M_cur = _M_last;
}
--_M_cur;
return *this;
}
_Self operator--(int) {//后置--重载
_Self __tmp = *this;
--*this;
return __tmp;
}
_Self& operator+=(difference_type __n)
{
difference_type __offset = __n + (_M_cur - _M_first);
if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
_M_cur += __n;
else {
difference_type __node_offset =
__offset > 0 ? __offset / difference_type(_S_buffer_size())
: -difference_type((-__offset - 1) / _S_buffer_size()) - 1;
_M_set_node(_M_node + __node_offset);
_M_cur = _M_first +
(__offset - __node_offset * difference_type(_S_buffer_size()));
}
return *this;
}
_Self operator+(difference_type __n) const
{
_Self __tmp = *this;
return __tmp += __n;
}
_Self& operator-=(difference_type __n) { return *this += -__n; }
_Self operator-(difference_type __n) const {
_Self __tmp = *this;
return __tmp -= __n;
}
reference operator[](difference_type __n) const { return *(*this + __n); }
bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; }
bool operator!=(const _Self& __x) const { return !(*this == __x); }
bool operator<(const _Self& __x) const {
return (_M_node == __x._M_node) ?
(_M_cur < __x._M_cur) : (_M_node < __x._M_node);
}
bool operator>(const _Self& __x) const { return __x < *this; }
bool operator<=(const _Self& __x) const { return !(__x < *this); }
bool operator>=(const _Self& __x) const { return !(*this < __x); }
void _M_set_node(_Map_pointer __new_node) {
_M_node = __new_node;
_M_first = *__new_node;
_M_last = _M_first + difference_type(_S_buffer_size());
}
};
图示:
四、deque的操作
deque.begin()返回指向第一个元素的迭代器
deque.end()返回指向最后一个元素下一个位置的迭代器
deque.rbegin()返回指向反向队列的第一个元素的迭代器
deque.rend()返回指向反向队列的最后一个元素的下一个位置
deque.assign(n,num)将n个num拷贝复制到容器deque中
deque.assign(beg,end)将[beg,end)区间的数据拷贝复制到容器deque
deque.front()访问容器的第一个元素
deque.back()访问容器的最后一个元素
deque.size()返回容器中实际拥有的元素个数
deque.insert(pos,num)在pos位置插入元素num
deque.insert(pos,beg,end)在pos位置插入区间为[beg,end)的元素
deque.erase(pos)删除pos位置的元素
deque.erase(beg,end)删除区间为[beg,end)的元素
deque.push_back(num)在末尾位置插入元素
deque.pop_back()删除末尾位置的元素
deque.push_front(num)在开头位置插入元素
deque.pop_front()删除开头位置的元素