C++序列式容器(三):deque

1. 概述

deque是双向开口的连续线性空间,可以在头尾两端分别做插入和删除操作。主要维护了一块map(不是stl的map)作为主控。map是一小块连续空间,每个节点都指向另一段连续性空间,也称缓冲区。该缓冲区即是存储空间主体。当map满载,则会分配更大的空间作为map。其主要结构体如下:

	class deque{
	public: 
		typedef T value_type;
		typedef value_type* pointer;
		...
	protected:
		//元素的指针的指针
		typedef pinter* map_pointer;
		// 指向map节点
		map_pointer map;
		// map容纳的指针数量
		size_type map_size;
		...
		}

内存结构如下图:
在这里插入图片描述

2. 迭代器

迭代器主要保存了四个指针:
cur 指向当前缓冲区的某个元素
first 指向当前缓冲区的头节点
last 指向当前缓冲区的尾节点
node 指向缓冲区对应的map节点

支持了一个方法set_node可以跳缓冲区,该方法重新指定node,first和last。当在头节点自减或者在尾节点自增的时候,会通过set_node跳到另一个缓冲区,并指定cur指针。

3. 构造与内存管理

初始化的时候会计算map长度和填充数据所占用map长度,尽量在map中间展开,从而使两边的扩充空间一样大。
finish指向最后一个空闲节点,尾端插入的时候,如果刚好是缓冲区的最后一个备用节点,会在map后端分配新节点,设置插入的值,并改变finish迭代器的指针指向新缓冲区的头节点。
往后插入节点,如果只剩一个备用节点的时候,会判断一次map是否扩容。方法如下:

	void reserve_map_at_back(size_type nodes_to_add=1){
		// map指向map首地址。
		if(nodes_to_add+1>map_size-(finish.node-map))
			reallocate_map(nodes_to_add, false);
	}

从前端插入的处理逻辑类似。

在中间插入或移除节点的时候,会判定节点前后的数据长度,按少的一端去做元素移动,因此越靠近中间段的数据变更,效率也越低。

发布了12 篇原创文章 · 获赞 1 · 访问量 122

猜你喜欢

转载自blog.csdn.net/formst001/article/details/104835158