c++ stl deque(双向开口的分段连续线性空间)

1.deque

  vector是单向开口的连续线性空间,deque则是一种双向开口的连续线性空间。所谓双向开口,意思是可以在头尾两端分别做元素的插入和删除操作。vector当然也可以在头尾两端进行操作,但是其头部操作效率奇差,无法被接受。

  deque和vector的最大差异,一在于deque允许于常数时间内对起头端进行元素的插入或移除操作,二在于deque没有所谓容量capacity观念,因为它是动态地以分段连续空间组合而成,随时可以增加一段新的空间并链接起来。

deque的中控器:

   deque系由一段一段的定量连续空间构造。一旦有必要在deque的前端或尾端增加新空间,便配置一段定量连续空间,串接在整个deque的头端或尾端。deque的最大任务,便是在这些分段的定量连续空间上,维护其整体连续的假象,并提供随进存取的接口。

  分段连续线性空间,就必须有中央控制,而为了维护整体连续的假象,数据结构的设计及迭代器前进后退等操作都颇为繁琐。

  deque采用一块所谓的map(注意,不是STL的map容器)作为主控。这里所谓map是一小块连续空间,其中每个元素(此处称为一个节点,node)都是指针,指向另一段(较大的)连续线性空间,称为缓冲区。缓存区才是deque的存储空间主体。SGI STL允许我们指定缓冲区大小,默认值0表示将使用512bytes缓冲区

    template <class T,class Alloc = alloc,size_t BufSiz = 0>
    class deque
    {
    public:
        typedef T value_type;
        typedef value_type* pointer;
        ... 	
    protected:
        typedef pointer* map_pointer;
    protected:
        map_pointer map;
        size_type map_size;
        ...
    }

deque的迭代器:

deque是分段连续空间。维持其“整体连续”假象的任务,落在了迭代器的operator++和operator--两个运算子身上。deque迭代器具备结构,1.必须能够指出分段连续空间(缓冲区)在哪里;2.必须能够判断自己是否已经处于其所在缓冲区的边缘;3.必须随时掌握控制中心(map)。

    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 __deque_iterator self;
        T* cur;
        T* first;
        T* last;
        map_pointer node;
        ...
    }

deque的数据结构:

  deque除了维护一个先前说过的指向map的指针外,也维护start,finish两个迭代器,分别指向第一缓冲区的第一个元素和最后缓冲区的最后一个元素(的下一个位置)。此外,它当然也必须记住目前的map大小。因为一旦map所提供的节点不足,就必须重新配置更大的一块map。

    template <class T,class Alloc = alloc,size_t BufSiz = 0>
    class deque
    {
    public:
        typedef T value_type;
        typedef value_type* pointer;
        typedef size_t size_type;
    public:
        typedef __deque_iterator<T,T&,T*,BufSiz> iterator;
    protected:    
        iterator start;
        iterator finish;
        map_pointer map;
        size_type map_size;
        ...
    }


2.函数成员

2.1构造函数:

/// Creates an empty deque.
deque();
/// Creates a deque with n elements.
deque(size_type n);
/// Creates a deque with n copies of t.
deque(size_type n, const T& t);
/// The copy constructor.
deque(const deque&);
/// Creates a deque with a copy of a range.
template <class InputIterator> deque(InputIterator f, InputIterator l);

2.2析构函数:

/// The destructor.

2.3插入元素:

/// Inserts a new element at the beginning.
void push_front(const T&);
/// Inserts a new element at the end.
void push_back(const T&);
/// Inserts x before pos.
iterator insert(iterator pos, const T& x);
/// Inserts the range [f, l) before pos.
template <class InputIterator> void insert(iterator pos, InputIterator f, InputIterator l);
/// Inserts n copies of x before pos.
void insert(iterator pos, size_type n, const T& x);

2.4删除元素:

/// Erases the element at position pos.
iterator erase(iterator pos);
/// Erases the range [first, last)
iterator erase(iterator first, iterator last);
/// Erases all of the elements.
void clear();

2.5返回元素指针或元素:

/// Returns an iterator pointing to the beginning of the deque.
iterator begin();
/// Returns an iterator pointing to the end of the deque.
iterator end();
/// Returns a reverse_iterator pointing to the beginning of the reversed deque.
reverse_iterator rbegin();
/// Returns a reverse_iterator pointing to the end of the reversed deque.
reverse_iterator rend();
/// Returns the first element.
reference front();
/// Returns the last element.
reference back();

2.6其他:

/// Returns the size of the deque.
size_type size() const;
/// Returns the largest possible size of the deque.
size_type max_size() const;
/// Returns the n'th element.
bool empty() const;

3.实例

#include <iostream>
#include <algorithm>
#include <deque>

int main()
{
    typedef std::deque<int> IDEQUE;
    IDEQUE::iterator iditr;
    IDEQUE ideque(5,10);            // 10 10 10 10 10

    /// 1.插入元素
    /// 1.1尾部插入元素
    ideque.push_back(11);           // 10 10 10 10 10 11
    ideque.push_back(12);           // 10 10 10 10 10 11 12
    /// 1.2头部插入元素
    ideque.push_front(9);           // 9 10 10 10 10 10 11 12
    ideque.push_front(8);           // 8 9 10 10 10 10 10 11 12
    /// 1.3指定位置插入元素
    iditr = find(ideque.begin(),ideque.end(),10);
    if(iditr != ideque.end())
        ideque.insert(iditr,50);    // 8 9 50 10 10 10 10 10 11 12

    /// 2.删除元素
    /// 2.1删除尾部元素
    ideque.pop_back();              // 8 9 50 10 10 10 10 10 11
    /// 2.2删除头部元素
    ideque.pop_front();             // 9 50 10 10 10 10 10 11
    /// 2.3删除指定位置元素
    iditr = find(ideque.begin(),ideque.end(),50);
    if(iditr != ideque.end())
        ideque.erase(iditr);        // 9 10 10 10 10 10 11
    /// 2.4清空所有元素
    ideque.clear();                 // empty

    /// 3.访问元素
    ideque.push_back(16);
    ideque.push_back(17);
    ideque.push_back(18);           // 16 17 18
    /// 3.1访问尾部元素
    ideque.back();                  // 18
    /// 3.2访问头部元素
    ideque.front();                 // 16

    /// 4.其他
    /// 4.1容器尺寸
    ideque.size();                  // 3
    /// 4.2容器最大尺寸
    ideque.max_size();              // 4611686018427387903
    /// 4.3容器是否为空
    ideque.empty();                 // 0

    return 0;
}

4.参考文献

  本文内容摘录于《STL源码剖析》

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值