深度剖析deque

3 篇文章 0 订阅

deque

1、deque概述

vector是单向开口的连续线性空间,而deque是双向开口的连续线性空间。

vectordeque最大的差异:

  1. deque允许在常数时间内对头端进行元素的插入和移除操作
  2. deque没有“容量”的概念,因为它是以动态地连续空间组合而成,随时可以增加一段新的空间并链接起来。

2、deque的中控器

deque采用一块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;	// 指向map,map是块连续空间,其中的每个元素都是一个指向一块连续线性空间缓冲区的指针
    size_type map_size; // map内容纳多少指针
};

3、deque的迭代器

deque是分段连续空间,维持其"整体连续"的假象的任务。

deque的迭代器的大致结构如下:

template<class T, class Ref, class Ptr, size_t BufSiz>
struct __deque_iterator{
 ...
	// 保持与容器的联结
	T* cur;			// 此迭代器所指之缓冲区的现行元素
    T* first;		// 此迭代器所指之缓冲区的头
    T* last;		// 此迭代器所指缓冲区的尾部(含备用空间)
    map_poinetr node;	// 指向管控中心
}

对迭代器进行加、减、前进、后退的各类操作中,最关键的是:一旦行进到缓冲区边缘,要特别当心,视前进或后退而定,可能需要调用set_node()跳一个缓冲区:

void set_node(map_point new_node)
{
    node = new_node;
    first = *new_node;
    last = first + difference_type(buffer_size());
}

4、deque的数据结构

  • deque除了维护先前说过的指向map的指针外,也维护startfinish两个迭代器,分别指向第一缓冲区的第一个元素和最后缓冲区的最后一个元素的下一个位置。
  • 此外,也必须记住目前的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:
    // 元素的指针的指针
    typedef poinetr* map_pointer;
    
protected:
    iterator start;			// deque的第一个节点
    iterator finish;		// 最后一个节点
    
    map_pointer map;		// 指向map,其中每个元素是指向连续线性空间的地址
    
    size_type map_size;		// map可以容纳多少个指针
......
}

有了以上结构,以下机能便可请以完成:

iterator begin() { return start; }
iterator end() { return finish; }
...

5、deque的元素操作

构造与赋值

deque();                                    // 默认构造
explicit deque(size_type count, const T& value = T(), const Allocator& alloc = Allocator());
template <class InputIt>
deque(InputIt first, InputIt last, const Allocator& alloc = Allocator());
deque(const deque& other);                  // 拷贝构造
deque(deque&& other) noexcept;              // 移动构造
~deque();                                   // 析构

deque& operator=(const deque& other);       // 拷贝赋值
deque& operator=(deque&& other) noexcept;   // 移动赋值
void assign(size_type count, const T& value); // 赋值
template <class InputIt>
void assign(InputIt first, InputIt last);   // 范围赋值

元素访问

// 访问指定位置元素
T& at(size_type pos); 

// 下标访问
T& operator[](size_type pos);    
// 常量访问
const T& at(size_type pos) const;      
// 常量下标访问
const T& operator[](size_type pos) const;   


T& front();                                  // 获取队头元素
T& back();                                   // 获取队尾元素
const T& front() const;                      // 常量获取队头元素
const T& back() const;                       // 常量获取队尾元素

修改容器

void push_back(const T& value);              // 在队尾添加元素
void push_front(const T& value);             // 在队头添加元素
void pop_back();                             // 删除队尾元素
void pop_front();                            // 删除队头元素
void insert(const_iterator pos, const T& value); // 插入元素
void erase(const_iterator pos);              // 删除指定位置元素
void clear();                                // 清空容器
void resize(size_type count, const T& value = T()); // 调整大小

容量

size_type size() const;                      // 获取元素数量
size_type max_size() const;                  // 最大容量
bool empty() const;                          // 检查是否为空
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值