STL源码剖析之序列容器deque

一、定义

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()删除开头位置的元素


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值