zoukankan      html  css  js  c++  java
  • 序列式容器

    容器结构分类

    这里的衍生,并非继承关系,而是一种包含关系。
    例如heap中包含一个vector。

    通过萃取机traits萃取迭代器的型别

    template <class I>
    struct iterator_traits { //traits是特性之意
    	typedef typename I::value_type value_type;
    };
    //两个偏特化(partial specialization)
    template <class T>
    struct iterator_traits<T*> {
    	typedef T value_type;
    };
    template <class T>
    struct iterator_traits<const T*> {
    	typedef T value_type; //注意是T而不是const T,因为value_type的主要目的是用来声明变量,而声明一个无法被赋值的变量是没有什么用的(const T),所以要去掉const
    };
    //于是当需要知道I的value_type时,便可以这么写:
    template<typename I>
    void algorithm(...) {
    	typename iterator_traits<I>::value_type v1;
    }
    

    容器list

    list在要内存时,不光需要一个指针,还需要指向前后的两个指针。

    list的定义

    //list的定义
    	template<class T, class Alloc = alloc>
    	class list {
    	protected:
    		typedef __list_node<T> list_node;
    	public:
    		typedef list_node* link_type;
    		//G2.9编译器的iterator
    		typedef __list_iterator<T, T&, T*> iterator;
    		//G4.9编译器的iterator
    		typedef _List_iterator<_Tp> iterator;
    	portected:
    		link_type node;
    	};
    

    list的node定义

    G2.9编译器的设计是如下所示:其中前向指针和后向指针,指向的都是void类型,所以sizeof(list)是4个字节,就是一个指向数据的指针。

    //list节点的定义
    	template <class T>
    	struct __list_node {
    		typedef void* void_pointer;
    		void_pointer prev;
    		void_pointer next;
    		T data;
    	};
    

    G4.9版本在G2.9版本的基础之上,将node部分拆分成了两个部分,一个是_list_node_base,改变了G2.9版本的前向和后向指针的指向类型,另外node是继承_List_node_base后,再加上数据部分,如下所示:

    //G4.9编译器,list节点的定义:
    	struct _List_node_base {
    		_List_node_base* _M_next;
    		_List_node_base* _M_prev;
    	};
    	template<typename _Tp>
    	struct _List_node : public _List_node_base {
    		_Tp _M_data;
    	};
    

    list的iterator

    list的存储是非连续空间,所以list的iterator不能是普通指针。而是定义一个class来模拟指针,称之为smart pointer


    如上图红色的泡泡,当list的iterator加一时,应该指向下一个节点的位置。所以list的iterator是一个smart pointer.
    每个iterator要有5个typedef,因为迭代器是容器和算法之间的桥梁,所以迭代器必须定义这五种typedef,以便于回答算法的提问:
    传入类型T的参数,直接T::iterator_category,就可以得到迭代器的类型。

    • iterator_category
    • value_type
    • difference_type
    • pointer
    • reference
      list的五个reference如下所示:
    //list的五个typedef定义
    template<typename _TP>
    struct _List_iterator {
    	typedef std::bidirectional_iterator_tag iterator_category;
    	typedef _Tp value_type;
    	typedef _Tp* pointer;
    	typedef _Tp& reference;
    	typedef ptrdiff_t difference_type;
    };
    

    还有一大堆的操作符重载。

    //list的iterator的定义
    	template <typename _Tp>
    	struct _List_iterator {
    		typedef _Tp* poinetr;
    		typedef _Tp& reference;
    	};
    

    容器vector

    vector的扩充方式是两倍增长,换一个内存后进行两倍增长。

    vector的定义

    //vector的定义
    template <class T,class Alloc = alloc>
    class vector{
    public:
    	typedef T value_type;
    	typedef value_type* iterator;//T*
    	typedef value_type& reference;
    	typedef size_t size_type;
    protected:
    	iterator start;
    	iterator finish;
    	iterator end_of_storage;
    public:
    	iterator begin() { return start; }
    	iterator end() { return finish; }
    	size_type size() const { //大小 finish-start
    		return size_type(end() - begin());
    	}
    	size_type capacity() const { //容量
    		return size_type(end_of_storage - begin());
    	}
    	bool empty() const { return begin() == end(); }
    	reference operator[](size_type n) { //连续空间的中括号
    		return *(begin() + n);
    	}
    	reference front() { return *begin(); } //取出首个元素
    	reference back() { //取出尾部元素
    		return *(end() - 1);
    	}
    }
    

    vector的iterator

    //vector的迭代器设计
    template <class T, class Alloc = alloc>
    class vector {
    public:
    	typedef T value_type;
    	typedef value_type* iterator; //T*
    };
    vector<int>vec;
    vector<int>::iterator ite = vec.begin();
    

    vector 的大小

    vector的大小是三个指针,start,finish,end_of_storage,这三个指针的大小是12.

    array

    array的定义

    //array的定义
    template <typename _Tp, std::size_t _Nm>
    struct array{
    	typedef _Tp value_type;
    	typedef _Tp* pointer;
    	typedef value_type* iterator;
    
    	//支持0大小的数组生成
    	value_type _M_instance[_Nm ? _Nm : 1];
    
    	iterator begin() {
    		return iterator(&_M_instance[0]);
    	}
    	iterator end() {  //最后一个元素的下一个元素
    		return iterator(&_M_instance[_Nm]);
    	}
    };
    

    forward_list

    forward_list与list的区别

    单向链表与list的区别仅仅只在于一个是单向,一个是双向,其他都是相同的。

    deque

    deque是一个双向开口的连续线性空间,其实是动态的以分段连续空间组合而成 ,外界以为它是连续的。

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

    如上图所示,deque管理一个map(一小块连续空间),map是一个vector,其中每个元素是一个指针,指向另一段较大的连续线性空间,称为缓冲区。

    deque的定义

    //一个deque的大小是40个字节

    template <class T,class Alloc = alloc, size_t BufSiz = 0> //BufSizs是buffer的大小
    class deque {
    public:
    	typedef T value_type;
    	typedef __deque_iterator<T, T&, T*, BufSiz>iterator;
    protected:
    	typedef pointer* map_pointer; //T**
    protected:
    	iterator start; //大小是16个字节
    	iterator finish; //大小是16个字节
    	map_pointer map; //控制中心是个vector,是会2倍动态增长的 T** 指向指针的指针 大小是4
    	size_type map_size; //大小是4字节
    public:
    	iterator begin() { return start; }
    	iterator end() { return finish; }
    	iterator size() const { return finish - start; }
    };
    

    deque的iterator

    deque的迭代器包含四个部分:cur first last node

    //deque的iterator
    template <class T, class Ref, class Ptr,size_t BufSiz>
    struct __deque_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* cur;
    	T* first;
    	T* last;
    	map_pointer node;
    
    };
    

  • 相关阅读:
    找最后的字符
    统计指定数字和
    班级排队
    python编程题
    python函数题
    2019.6.24-2019.6.28(实训数据结构)3.数组编码求解问题
    2019.6.24-2019.6.28(实训数据结构)1.商品管理系统实训c++(实现的基本功能:初始化,创建表,插入,删除,更新,查询,链表数据与文件之间的转换)
    2019.6.24-2019.6.28(实训数据结构) 2.背包问题
    2019.6.24-2019.6.28(实训数据结构)4.树和二叉树应用项目
    2019.6.24-2019.6.28(实训数据结构)5.图的邻接矩阵表示
  • 原文地址:https://www.cnblogs.com/ccpang/p/12248323.html
Copyright © 2011-2022 走看看