• 【STL源码剖析读书笔记】【第4章】序列式容器之deque


    1、deque概述

    deque是一种双向开口的连续线性空间,可以在头尾两端分别做元素的插入和删除操作。

    deque没有容量的概念,它是动态地以分段连续空间组合而成,随时可以增加一段新的空间并链接起来。

    2、deque的中控器

    deque由一段一段的定量连续空间构成。一旦有必要在dequer前端或尾端增加新空间,便配置一段定量连续空间,串接在整个deque的头端或尾端。

    deque的最大任务是在这些分段的定量连续空间上,维护其整体连续的假象,并提供随机存取的接口。

    deque采用一块所谓的map作为主控。这里所谓map是一小块连续空间,其中每个元素(此处称为一个节点,node)都是指针,指向另一段(较大的)连续线性空间,称为缓冲区。缓冲区才是deque的储存空间主体。

    template<class T, class Alloc = alloc, size_t BufSiz = 0>
    class deque{
    public :
    	typedef	T value_type ;
    	typedef	value_type* pointer ;
    	...
    protected :
    	//元素的指针的指针(pointer of pointer of T)
    	typedef	pointer* map_pointer ; //其实就是T**
    
    protected :
    	map_pointer map ; //指向map,map是块连续空间,其内的每个元素
    					  //都是一个指针(称为节点),指向一块缓冲区
    	size_type map_size ;//map内可容纳多少指针
    	...
    };
    

    3、deque的迭代器

    deque是分段连续空间,维持”整体连续“假象的任务,落在迭代器的operator++和operator—两个运算子上。

    template<class T, class Ref, class Ptr, size_t BufSiz>
    struct __deque_iterator{ //未继承std::iterator
    	typedef	__deque_iterator<T,T&,T*,BufSize>	iterator ;
    	typedef	__deque_iterator<T,const T&,const T*,BufSize>	const_iterator ;
    	static	size_t	buffer_size() {return __deque_buf_size(BufSize,sizeof(T)) ;} 
    
    	//未继承std::iterator,所以必须自行撰写五个必要的迭代器相应型别
    	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 *cut ; //此迭代器所指之缓冲区中的现行(current)元素
    	T *first ; //此迭代器所指之缓冲区的头
    	T *last ;	//此迭代器所指之缓冲区的尾(含备用空间)
    	map_pointer node ; //指向管控中心
    	...
    };
    

    4、deque的数据结构

    deque除了维护一个指向map的指针外,也维护start,finish两个迭代器,分别指向第一缓冲区的第一个元素和最后缓冲区的最后一个元素(的下一个位置)。

    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 :
    	//元素的指针的指针(pointer of pointer of T)
    	typedef	pointer*	map_pointer ;
    protected:
    	iterator	start ; //表现第一节点
    	iterator	finish ; //表现最后一个节点
    	map_pointer	map ; //指向map,map是块连续空间,其每个元素都是个指针,指向一个节点(缓冲区)
    	size_type	map_size ; //map内有多少指针
    	...
    } ;
    

    5、deque的构造与内存管理

    #include<iostream>
    #include<deque>
    #include<algorithm>
    using namespace std;
    
    int main(){
    	deque<int,alloc,8> ideq(20, 9);//在VS2013中不支持,改成deque<int> ideq(20, 9);
    	cout << "size=" << ideq.size() << endl;
    
    	for (int i = 0; i < ideq.size(); ++i)
    		ideq[i] = i;
    
    	for (int i = 0; i < ideq.size(); ++i)
    		cout << ideq[i] << ' ';
    	cout << endl;
    
    	for (int i = 0; i < 3; i++)
    		ideq.push_back(i);
    
    	for (int i = 0; i < ideq.size(); ++i)
    		cout << ideq[i] << ' ';
    	cout << endl;
    	cout << "size=" << ideq.size() << endl;
    
    	ideq.push_back(3);
    	for (int i = 0; i < ideq.size(); ++i)
    		cout << ideq[i] << ' ';
    	cout << endl;
    	cout << "size=" << ideq.size() << endl;
    
    	ideq.push_front(99);
    	for (int i = 0; i < ideq.size(); ++i)
    		cout << ideq[i] << ' ';
    	cout << endl;
    	cout << "size=" << ideq.size() << endl;
    
    	ideq.push_front(98);
    	ideq.push_front(97);
    	for (int i = 0; i < ideq.size(); ++i)
    		cout << ideq[i] << ' ';
    	cout << endl;
    	cout << "size=" << ideq.size() << endl;
    
    	deque<int>::iterator it = find(ideq.begin(), ideq.end(), 99);
    	cout << *it << endl;
    	
    	system("pause");
    	return 0;
    }
    

    里面的元素都是9,上图并未显示。





  • 相关阅读:
    Hardware Virtualization
    Windows Vista 中脱机文件的更改
    Vista右键打开方式有两个记事本。
    SQL Server 2008 无法采用SQL认证模式登录(已解决)
    .NET 书籍推荐
    快速掌握一个语言最常用的50% 孟岩
    [原创] 大内存妙用 之 Readyboost 篇
    .Net 中的反射 14
    pureMVC使用实践
    有关于movieClip的一些问题
  • 原文地址:https://www.cnblogs.com/ruan875417/p/4558324.html
Copyright © 2020-2023  润新知