STL浅析 deque

vector是单向开口的连续线性空间,deque是双向开口的连续线性空间。所谓双向开口,就是可以在头尾两端做插入和删除。虽然vector在头部做插入和删除也可以实现,但效率很差,因为会不断的移动整个数组。而deque在头部的插入和删除是O(1)的时间复杂度。deque和vector的差异1.deque允许在O(1)时间复杂度内对头部进行插入和删除。2.deque没有容量的概念,因为它是...
摘要由CSDN通过智能技术生成

vector是单向开口的连续线性空间,deque是双向开口的连续线性空间。
所谓双向开口,就是可以在头尾两端做插入和删除。
虽然vector在头部做插入和删除也可以实现,但效率很差,因为会不断的移动整个数组。
而deque在头部的插入和删除是O(1)的时间复杂度。

deque和vector的差异

1.deque允许在O(1)时间复杂度内对头部进行插入和删除。
2.deque没有容量的概念,因为它是动态地以分段连续空间组合而成的。(也就是多段连续空间首尾相连)。所以也不用像vector一样[开辟空间,复制元素,释放旧空间]。
3.虽然deque也提供随机访问,但是它的迭代器并不是原生指针。相比起来要复杂得多,因此也影响了运算效率,所以尽量使用vector少用deque。

deque的中控器

deque 系由一段一段的定量连续空间构成。一旦有必要在 deque 的前端或尾端增加新空间,便配置一段定量连续空间,串接在整个 deque 的头端或尾端。deque 的最大任务,便是在这些分段的定量连续空间上,维护其整体连续的假象,并提供随机存取的界面。避开了「重新配置、复制、释放」的轮回,代价则是复杂的迭代器架构。这也就是中控器存在的理由了。

deque采用了一块所谓的map(注意,不是STL的map容器)作为主控。这里所说的map是一段连续的空间,其中的每个元素都是一个指针,指向deque的某一块连续线性空间的起始位置。这样就将多个连续空间结合起来了。


// SGI STL运行自定义缓冲区大小,BufSiz为0时默认使用至少512bytes的缓冲区
// (原作者说是512应该不是很准确,见下文__deque_buf_size的解释)
template <class T, class Alloc = alloc, size_t BufSiz = 0>
class deque {
public:
    typedef T 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;

protected:
    typedef pointer* map_pointer;  // 元素指针的指针,指向map的指针
    map_pointer map;      // 指向map, map是一个连续的空间, 其中的每个元素都是一个指向缓冲区的指针
    size_type map_size;   // map容量
...
}

我们可以发现,map其实是一个T**,本身是指针[指向map的指针],指向的连续空间存储的又是指针[指向deque连续空间的指针]。
在这里插入图片描述
总结一下就是存储了deque的各个连续空间都在哪里。

deque的迭代器

deque是分段的连续空间,维护其[整体连续]假象的人物,就落在了迭代器operator++和operator–两个运算子身上。
deque的迭代器不仅需要在连续空间上移动,还需要在连续空间之间移动,所以必须依靠上面所说的中控器map。

为了方便理解,我们不妨将deque中的一块连续空间称为一块缓冲区

template <class T, class Ref, class Ptr, size_t BufSiz>
struct __deque_iterator {
    typedef __deque_iterator<T, T&, T*, BufSiz>             iterator;
    typedef __deque_iterator<T, const T&, const T*, BufSiz> const_iterator;
    static size_t buffer_size() {return __deque_buf_size(BufSiz, sizeof(T)); }

    typedef random_access_iterator_tag iterator_category;
    typedef T value_type;
    typedef Ptr pointer;
    typedef Ref reference;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    typedef T** map_pointer;

    typedef __deque_iterator self;

    // 保持与容器的联结
    T* cur;           // 缓冲区中的当前元素
    T* first;         // 缓冲区中的头
    T* last;          // 缓冲区中的尾
    map_pointer node; // 指向中控器
...
}

在这里插入图片描述
deque的缓冲区大小是固定的,具体值由__deque_buf_size函数计

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值