C++STL容器与迭代器

文章目录

To-Do:

  1. vector倍长的方式
    主要是验证与拓展
  2. list中的所有成员详解
    本次只针对期末可能用到的, 箱套充分使用, 需要进一步拓展
  3. deque进一步了解
  4. array进一步了解
  5. forward_list进一步了解

容器的概述与使用:

STL中的容器是用来存储数据集合的通用数据结构。

通过使用容器,用户不再需要使用C风格的数组、链表甚至堆栈
容器通过模板实现,可以初始化存储任意满足基本要求的任意数据类型

各种容器:

  • 顺序容器:vector、list、deque、array、forward_list
  • 关联容器:map、multimap、set、multiset
  • 容器适配器:queue、priority_queue、stack
  • 无序关联容器:unordered_map、unordered_set, unordered_multimap、unordered_multiset
  • 其它:bitset、string

使用容器存储时对数据类型的基本要求:

通常使用STL储存自定义数据类型时, 至少需要定义以下函数进行容器功能的实现, 否则会有一些功能(容器函数)无法实现

  • 拷贝构造函数:插入元素时调用
  • 移动构造函数:构造元素并销毁源元素
    (可选, 用于提升性能)
  • 析构函数:清除元素
  • 赋值运算符:修改某个元素
  • 移动赋值运算符:赋值后要销毁源元素
    (可选, 用于提升性能)
  • 缺省构造函数
  • operator==:比较元素
  • operator<:比较元素

STL 迭代器

由于迭代器在基础部分中已经有足够多的学习, 这里直接Copy并做格式优化与内容删减

迭代器简介:

  • STL库中所有容器都有基于特定容器的迭代器

  • 可将迭代器理解为遍历数组元素的智能指针

  • 迭代器通过++运算移动并引用下一个元素
    通过*或->运算符访问当前元素

    此为每个迭代器都应该具备的基本功能

  • 一些特定容器的迭代器提供更多的功能:
    如==、!=、–运算符, 以及随机访问等

  • 同C++中的其他指针一样, 迭代器也遵循半开区间

    合法的迭代器最多只能指向容器中最后一个元素的后一个位置, 其他的指向都是UB未定义的

迭代器の类型:

这里以vector为例:

iterator begin() noexcept;
const_iterator begin() const noexcept;

reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;

const_iterator cbegin() const noexcept;

const_reverse_iterator crbegin() const noexcept;

迭代器的两个特殊的属性:

  • const 常量迭代器

    • 相当于常量指针, 即顶层const指针, 各种特性与其相同
      不可修改指向的元素, 声明必须初始化, 等等

    • 当容器内的元素为常量const时, 会自动返回常量迭代器

  • reverse 反向迭代器

    和普通的迭代器移动方向相反:

    • ++ 运算将访问前一个元素,而 – 运算则访问下一个元素
    • 半开半闭区间也相反, 可以指向第一个元素的前一个位置

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XY6nyLAF-1579571086299)(C:\Users\Janus II\AppData\Roaming\Typora\typora-user-images\image-20191213090528886.png)]

迭代器的使用:

//声明一个set的迭代器  
set<int>::iterator it;

*iter    		//对iter进行解引用,返回迭代器iter指向的元素的引用

iter->men   	//对iter进行解引用,获取指定元素中名为men的成员。等效于(*iter).men

++iter  iter+  	//给iter加1,使其指向容器的下一个元素

--iter  iter-- 	//给iter减1,使其指向容器的前一个元素

iter1==iter2  iter1!=iter2  
				//比较两个迭代器是否相等,当它们指向同一个容器的同一个元素或者
				//都指向同同一个容器的超出末端的下一个位置时,它们相等
				
//只有vector和queue容器提供迭代器算数运算(即加减乘除)和除!=和==之外的关系运算:
iter+n   iter-n   	
				//在迭代器上加(减)整数n,将产生指向容器中钱前面(后面)第n个元素的迭代器。
				
iter1+=iter2  iter1-=iter2		
				//将iter1加上或减去iter2的运算结果赋给iter1。
				
iter1-iter2      		
				//两个迭代器的减法,得出两个迭代器的距离(特有的difference_type类型) 
				
 >,>=,<,<=     	//元素靠后的迭代器大于靠前的迭代器。
  • 拓展
    difference_type类型类似size_type类型, 用来表示两个迭代器之间的 距离 , 比如两个迭代器相减得到的数据类型就是difference_type, 他是一个有符号整型数, 具体为:

迭代器的失效:

注意: 为了防止迭代器失效,尽可能的不要使用迭代器修改元素

若是必要, 则也不要在使用了迭代器的循环体,都不要向迭代器所属的容器添加元素

向容器中添加或删除元素都有可能会是迭代器失效, 即失效后的迭代器不在指向任何元素(类似野指针).

  • 对于vector & string :

    添加元素后(如用push_back()), 如果导致储存空间被重新分配, 则原先指向容器的所有迭代器都会失效; 否则只是插入位置后的元素的迭代器会失效;删除元素之后的迭代器都会失效;

  • 对于deque:

    向任何位置插入&添加元素都会导致迭代器全面失效

  • 对于list & forward_list:

    不论怎么插&删, 迭代器都是有效的

顺序容器:

vector:

 vector也在基础部分中进行了较为详细的拓展了, 这里只做一些优化 

//vector通用模板
template < class T, class Alloc = allocator<T> > class vector; 

vector特性:

vector是一个能够存放任意类型的动态数组,能够增减数据,

  • 其与传统C数组类似, 元素在内存中连续储存
  • 支持快速随机访问
  • 支持在尾部高效添加元素
  • 能够在中间低效添加元素

vector高效延长的方式:

通常采用的是倍长的方式, 这也是C++中广泛采用的方法

通常在创建时给予一个既定的长度足以容纳下初始化后的所有元素, 一旦添加的元素超过了上限, 则将容量扩大到原来的两倍, 并把原来的元素拷贝到新的空间中

vector的使用:

构造与析构

通常, vector的初始化基本不预设其大小, 即创建一个空的vector, 因为vector可以非常高效的延长, 而预设vector的长度可能使性能更差, 除非是需要设置n个元素值都一样

//是时候献上真正的函数声明了:
//默认初始化:
explicit vector (const allocator_type& alloc = allocator_type());	
//注意前头的explicit

//填充初始化(就是画图的填充):
explicit vector (size_type n);
         vector (size_type n, const value_type& val,
                 const allocator_type& alloc = allocator_type());
                 
//范围初始化(部分拷贝):
template <class InputIterator>
  vector (InputIterator first, InputIterator last,
          const allocator_type& alloc = allocator_type());
          
//拷贝初始化:	
vector (const vector& x);
vector (const vector& x, const allocator_type& alloc);

//这3个TM是啥.....
vector (vector&& x);
vector (vector&& x, const allocator_type& alloc);
initializer list (6)	
vector (initializer_list<value_type> il,
       const allocator_type& alloc = allocator_type());

/******以下为旧的构造函数解释, Low了点*******************************/	

vector<Type> VectorName       
 // 创建一个空的vector, 类型为Type, 标识符为VectorName
 
vector <Type>c1(c2)         // 复制一个vector, 将c2复制给c1

vector <Type>c(n)           // 创建一个vector,含有n个数据,数据均已缺省构造产生 
							//[会自动赋给一个初值, 但是根据数据类型进行的, 所以不一定是0]
							
vector <Type>c(n, elem)     // 创建一个含有n个elem拷贝的vector

int a[]={1,2,3,4,5,6}; 
vector<Type> v5(a,a+4);  	//将数组a到a+4赋给v5

vector<int>v3(10,2);  		//创建一个含义10个int, 且值都为2的vector

//也可以用 大括号{} 进行列表初始化 :
vector<int> v4={10,2}; 		//v4有两个int元素, 分别为10, 2;  
							//和数组的初始化方法一样 [注意与圆括号()创建法不同!]

//析构函数
vectorName.~vector ()      	// 销毁所有数据,释放内存

成员函数:

//-----------------------
//iterator迭代器系列函数:

//返回首迭代器
iterator begin() noexcept;
const_iterator begin() const noexcept;

//返回尾迭代器
iterator end() noexcept;
const_iterator end() const noexcept;

//-------------------------------------------------------------
//Capacity容量系列函数, 用于返回和设置容量

//返回容器中实际数据的个数。
size_type size() const noexcept;

//返回容器可承载的最大的元素数量, 包括可重新分配内存而达到的最大值
size_type max_size() const noexcept;

//返回当前申请的内存大小(以字节为单位), 由当前最大可容纳的元素个数觉得
size_type capacity() const noexcept;

//设置容器的当前元素数量为n个
//如果n大于当前元素数量, 则将新增的元素初始化成val, 如果未提供val, 则使用默认的构造函数
//如果n小于当前元素数量, 则删除多余的元素
void resize(size_type n);
void resize(size_type n, const value_type& val);

//设置容器的大小至少可容纳n个元素
//如果n大于当前capacity, 则扩容到n
//如果n小于当前capacity, 啥也不干
void reserve(size_type n);

//判断容器是否为空
bool empty() const noexcept;

//-----------------------------------------------------------------------
//Element access元素访问系列函数:

//类似于C原生数组的下标访问:
	  reference operator[] (size_type n);
const_reference operator[] (size_type n) const;

//传回索引idx位置的元素的引用, 越界会抛出out_of_range
      reference at(size_type n);
const_reference at(size_type n) const;
					
//传回最后一个元素的引用(注意不检测是否初始化)
      reference back();
const_reference back() const;

//返回第一个元素的引用
      reference front();
const_reference front() const;

//返回一个指向vector首元素的直接内存指针(可用于C&C++混合编程)
//由于vector的元素是连续分配内存的, 所以可以通过指针偏移来访问元素	
      value_type* data() noexcept;
const value_type* data() const noexcept;
	
//----------------------------------------
//Modifiers编辑器系列函数, 用于修改元素

//拷贝赋值, 与拷贝构造函数相似......吧
void assign(InputIterator first, InputIterator last);	
void assign(size_type n, const value_type& val);
void assign(initializer_list<value_type> il);	//可变参数

//向容器的末尾压入一个元素
//如果这导致当前的元素数量超过capacity, 则会导致储存空间重新分配
void push_back(const value_type& val);
void push_back(value_type&& val);

//弹出最后一个元素, 使size-1
void pop_back();

//在pos位置插入一个或n个新元素, 并初始化为val, 导致size+1
//返回指向插入元素中第一个元素的迭代器
//如果这导致当前的元素数量超过capacity, 则会导致储存空间重新分配
//注意: 插入会导致pos后的元素被重新分配位置, 这是一个低效的操作
iterator insert(const_iterator position, const value_type& val);
iterator insert(const_iterator position, size_type n, const value_type& val);
template <class InputIterator>
//在pos位置插入从first到last的元素, 包括first, 但不包括last
iterator insert(const_iterator position, InputIterator first, InputIterator last);
iterator insert(const_iterator position, value_type&& val);
//不定参数版本
iterator insert(const_iterator position, initializer_list<value_type> il);

//删除制定的元素(直接删除元素释放内存, 而不仅仅是擦除数据), 导致size-1
//返回被删除元素的后一个元素的迭代器, 如果删除了最后一个元素, 则返回尾迭代器
//注意: 删除会导致pos后的元素被重新分配位置, 这是一个低效的操作
iterator erase(const_iterator position);
iterator erase(const_iterator first, const_iterator last);

//交换当前容器与相同类型的容器x中的元素
//注意: 此函数不会导致迭代器,引用和指针失效
void swap (vector& x);

//清除当前容器中的所有元素, 并将size置零
//注意: 使用此函数后储存空间可能会被重新分配
//但是如果需要强制重新分配, 通常使用vector<T>().swap(x);
void clear() noexcept;

//构造并在pos位置插入一个元素, 返回指向插入的新元素的迭代器
//功能上与insert类似, 但其避免了临时变量的产生
//insert采用的是将所提供的参数构造一个临时变量, 而后将其拷贝到pos位置
//emplace直接在pos位置用对应类型的构造函数构造一个元素, 所以即使构造函数为explicit也可以使用
template <class... Args>
iterator emplace(const_iterator position, Args&&... args);
//与push_back类似
template <class... Args>
  void emplace_back(Args&&... args);

//----------------------------------------------------------------------
//allocator空间配置器函数

//返回当前容器的空间配置器(这个还没学到...先等等)
allocator_type get_allocator() const noexcept;


//---------------------------------------------------------
//Non-member function overloads 非成员函数重载

//各个关系运算符的重载
(1)	
template <class T, class Alloc>
  bool operator== (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
(2)	
template <class T, class Alloc>
  bool operator!= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
(3)	
template <class T, class Alloc>
  bool operator<  (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
(4)	
template <class T, class Alloc>
  bool operator<= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
(5)	
template <class T, class Alloc>
  bool operator>  (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);
(6)	
template <class T, class Alloc>
  bool operator>= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);

//交换容器x与y的所有元素, 功能与成员函数swap相似
//此为泛型算法的重载版本, 效率较高(比成员函数swap高)
template <class T, class Alloc>
  void swap(vector<T,Alloc>& x, vector<T,Alloc>& y);


使用注意项:

  1. 赋值&添加:
    采用类似数组下标的方式对vector进行访问, 下标访问的元素必须是已经存在的元素, 所以不可以用下标法进行元素的添加, 只能用来修改以存在的元素
  2. 访问:
    可以使用下标法&STL通用迭代器进行元素的访问, 但通常使用迭代器, 这是作为C++程序员的习惯, 因为迭代器是STL容器中通用的, 但下标法只是vector的特性

list双向循环链表:

template < class T, class Alloc = allocator<T> > class list;

list特性:

list以节点来储存数据, 所以数据在内存中不连续

list的每个节点有三个域:前驱元素指针域、数据域和后继元素指针域

  • 前驱元素指针域保存了前驱元素的首地址;
  • 数据域则是本节点的数据;
  • 后继元素指针域则保存了后继元素的首地址

头节点的前驱元素指针域保存的是链表中尾元素的首地址,list的尾节点的后继元素指针域则保存了头节点的首地址, list实际上就构成了一个双向循环链表

由以上特点可得:

  • 支持常量时间的任意位置插入和删除操作
  • 对单个元素的访问为线性访问, 不支持随机访问, 只能用迭代器+±-

list的使用:

构造&析构函数:

//default (1)	
explicit list (const allocator_type& alloc = allocator_type());

//fill (2)	
explicit list (size_type n);
         list (size_type n, const value_type& val,
                const allocator_type& alloc = allocator_type());

//range (3)	
template <class InputIterator>
  list (InputIterator first, InputIterator last,
         const allocator_type& alloc = allocator_type());

//copy (4)	
list (const list& x);
list (const list& x, const allocator_type& alloc);

//move (5)	
list (list&& x);
list (list&& x, const allocator_type& alloc);

//initializer list (6)	
list (initializer_list<value_type> il,
       const allocator_type& alloc = allocator_type());

//copy (1)	
list& operator= (const list& x);

//move (2)	
list& operator= (list&& x);

//initializer list (3)	
list& operator= (initializer_list<value_type> il);

~list();

元素访问函数:

      reference front();
const_reference front() const;

      reference back();
const_reference back() const;

      iterator begin() noexcept;
const_iterator begin() const noexcept;

      iterator end() noexcept;
const_iterator end() const noexcept;

      reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;

      reverse_iterator rend() nothrow;
const_reverse_iterator rend() const nothrow;	

const_iterator cbegin() const noexcept;

const_iterator cend() const noexcept;

const_reverse_iterator crbegin() const noexcept;

const_reverse_iterator crend() const noexcept;

元素修改函数:

void push_front (const value_type& val);
void push_front (value_type&& val);
//************************************

void pop_front();
//************************************

void push_back (const value_type& val);
void push_back (value_type&& val);
//************************************

void pop_back();
//************************************

//single element (1)	
iterator insert (const_iterator position, const value_type& val);

//fill (2)	
iterator insert (const_iterator position, size_type n, const value_type& val);

//range (3)	
template <class InputIterator>
iterator insert (const_iterator position, InputIterator first, InputIterator last);

//move (4)	
iterator insert (const_iterator position, value_type&& val);

//initializer list (5)	
iterator insert (const_iterator position, initializer_list<value_type> il);
//************************************

iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);
//************************************

void clear() noexcept;
//************************************

容量函数

bool empty() const noexcept;
//************************************

size_type size() const noexcept;
//************************************

对象操作函数:

//entire list (1)	
void splice (const_iterator position, list& x);
void splice (const_iterator position, list&& x);

//single element (2)	
void splice (const_iterator position, list& x, const_iterator i);
void splice (const_iterator position, list&& x, const_iterator i);

//element range (3)	
void splice (const_iterator position, list& x,
             const_iterator first, const_iterator last);
void splice (const_iterator position, list&& x,
             const_iterator first, const_iterator last);
//************************************

void remove (const value_type& val);

template <class Predicate>
  void remove_if (Predicate pred);
//************************************

//(1)	
void unique();
//(2)	
template <class BinaryPredicate>
  void unique (BinaryPredicate binary_pred);
//************************************

//(1)	
  void merge (list& x);
  void merge (list&& x);
//(2)	
template <class Compare>
  void merge (list& x, Compare comp);
template <class Compare>
  void merge (list&& x, Compare comp);
//************************************

//(1)	
  void sort();
//(2)	
template <class Compare>
  void sort (Compare comp);

void reverse() noexcept;
//************************************

deque双端队列:

template < class T, class Alloc = allocator<T> > class deque;

deque特性:

deque可以看做是vector与list功能的结合

其元素在内存中的分布并不是连续的:

  1. 由一段一段的定量连续空间构成,第一个区块朝某个方向扩展,最后一个区块朝相反方向扩展;

  2. 管理这些分段的定量连续空间,维护其整体连续的假象,并提供随机存取的接口;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LZf21t5v-1579571086302)(C:\Users\Janus II\AppData\Roaming\Typora\typora-user-images\image-20191213183341711.png)]

所以, deque具有这些功能:

  1. 支持随机访问, 但是性能没有vector好

  2. 支持内部增删操作,但性能不及list

  3. 首尾两端能快速增删元素

但是, deque的效率没有vector和list高, 各功能处于vector与list间平衡的状态, 所以如果需要高效操作, 还是使用vector & list

array数组:

template < class T, size_t N > class array;

array特性:

array比vector更趋向于传统数组, 所以作为数组的替代更合适

  • 构造后大小固定,不再增加或收缩

  • 能够分配在栈上,vector需要分配在堆上

  • 元素在内存中连续储存

forward_list单向链表:

template < class T, class Alloc = allocator<T> > class forward_list;

forward_list特性:

  • 不支持反向迭代器, 只有正向迭代器
  • 没有指向最末元素的锚点
  • 无法随机访问
  • 支持常量时间的任意位置插入和删除操作

适配器容器:

queue队列:

template <class T, class Container = deque<T> > class queue;

queue特点:

队列遵循着FIFO(先进先出)的特点

  • 只能访问第一个和最后一个元素
  • 只能在容器的末尾添加新元素,只能从头部移除元素

queue的使用:

成员函数:

bool empty() const;

size_type size() const;

      reference& front();
const_reference& front() const;

      reference& back();
const_reference& back() const;

void push (const value_type& val);
void push (value_type&& val);

template <class... Args> void emplace (Args&&... args);

void pop();

非成员函数:

void swap (queue& x) noexcept(/*see below*/);

priority_queue优先队列:

template <class T, class Container = vector<T>,
  class Compare = less<typename Container::value_type> > class priority_queue;

priority_queue特性:

优先队列具有最高级先出 (first in, largest out)的特点

实际上就是将queue中的弹出规则进行了修正
其他的特性与queue基本相同

priority_queue使用:

成员函数:

bool empty() const;

size_type size() const;

const_reference top() const;

void push (const value_type& val);
void push (value_type&& val);

template <class... Args> void emplace (Args&&... args);

void pop();

void swap (priority_queue& x) noexcept (/*see below*/);

template <class T, class Container, class Compare>
  void swap (priority_queue<T,Container,Compare>& x,
             priority_queue<T,Container,Compare>& y) noexcept(noexcept(x.swap(y)));

非成员函数:

void swap (queue& x) noexcept(/*see below*/);

stack堆栈:

template <class T, class Container = deque<T> > class stack;

stack特性:

stack与queue类似, 但是其遵守的是先进后出(FILO)的规则

  • 只能单端增删元素

stack用法:

成员函数:

bool empty() const;

size_type size() const;

      reference& top();
const_reference& top() const;

void push (const value_type& val);
void push (value_type&& val);

template <class... Args> void emplace (Args&&... args);

void pop();

void swap (stack& x) noexcept(/*see below*/);

非成员函数:

//(1)	
template <class T, class Container>
  bool operator== (const stack<T,Container>& lhs, const stack<T,Container>& rhs);

//(2)	
template <class T, class Container>
  bool operator!= (const stack<T,Container>& lhs, const stack<T,Container>& rhs);

//(3)	
template <class T, class Container>
  bool operator<  (const stack<T,Container>& lhs, const stack<T,Container>& rhs);

//(4)	
template <class T, class Container>
  bool operator<= (const stack<T,Container>& lhs, const stack<T,Container>& rhs);

//(5)	
template <class T, class Container>
  bool operator>  (const stack<T,Container>& lhs, const stack<T,Container>& rhs);

//(6)	
template <class T, class Container>
  bool operator>= (const stack<T,Container>& lhs, const stack<T,Container>& rhs);
//***************************

template <class T, class Container>
  void swap (stack<T,Container>& x, stack<T,Container>& y) noexcept(noexcept(x.swap(y)));

关联容器:

关联容器和顺序容器有着根本的不同:

  • 元素非线性储存
    通常以树的形式进行储存
  • 提供键到值的映射

所以, 通常, 关联容器不支持顺序容器中的位置相关的操作

pair:

#include <utility>		

template <class T1, class T2> struct pair;

pair特性:

将两个元素绑在一起作为一个合成元素

可以看成是两个元素的结构体struct, 但是比struct更加灵活

pair是其他关联容器的基础类, 所以通常很少直接使用pair, 而是用pair的衍生类模板, 如map

pair使用:

成员函数:

//copy (1)	
pair& operator= (const pair& pr);

template <class U, class V>
  pair& operator= (const pair<U,V>& pr);


//move (2)	
pair& operator= (pair&& pr)
           noexcept (is_nothrow_move_assignable<first_type>::value &&
                     is_nothrow_move_assignable<second_type>::value);

template <class U, class V>
  pair& operator= (pair<U,V>&& pr);


void swap (pair& pr) noexcept ( noexcept(swap(first,pr.first)) &&
                                noexcept(swap(second,pr.second)) );

非成员函数:

//(1)	
template <class T1, class T2>
  bool operator== (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs);

//(2)	
template <class T1, class T2>
  bool operator!= (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs);

//(3)	
template <class T1, class T2>
  bool operator<  (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs);

//(4)	
template <class T1, class T2>
  bool operator<= (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs);

//(5)	
template <class T1, class T2>
  bool operator>  (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs);

//(6)	
template <class T1, class T2>
  bool operator>= (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs);


template <class T1, class T2>
  void swap (pair<T1,T2>& x, pair<T1,T2>& y) noexcept (noexcept(x.swap(y)));


//lvalue (1)	
template <size_t I, class T1, class T2>
  typename tuple_element< I, pair<T1,T2> >::type&  get (pair<T1,T2>&  pr) noexcept;

//rvalue (2)	
template <size_t I, class T1, class T2>
  typename tuple_element< I, pair<T1,T2> >::type&& get (pair<T1,T2>&& pr) noexcept;

//const (3)	
template <size_t I, class T1, class T2>
  const typename tuple_element< I, pair<T1,T2> >::type&
    get (const pair<T1,T2>& pr) noexcept;

map:

template < class Key,                                     // map::key_type
           class T,                                       // map::mapped_type
           class Compare = less<Key>,                     // map::key_compare
           class Alloc = allocator<pair<const Key,T> >    // map::allocator_type
           > class map;

map特性:

map提供一对一的hash, 所以通常用在资料一对一映射(one-to-one)的情況

第一个可以称为关键字(key),每个关键字只能在map中出现一次
第二个可能称为该关键字的值(value)

  • map内部所有的数据都是有序的

  • 底层为红黑树

    所以支持元素快速查找, 时间复杂度为O(logN)

  • 元素不存在重复, 都是一对一映射

成员类型:

member type definition notes
key_type The first template parameter (Key)
mapped_type The second template parameter (T)
value_type pair<const key_type,mapped_type>
key_compare The third template parameter (Compare) defaults to: less<key_type>
value_compare Nested function class to compare elements see value_comp
allocator_type The fourth template parameter (Alloc) defaults to: allocator<value_type>
reference value_type&
const_reference const value_type&
pointer allocator_traits<allocator_type>::pointer for the default allocator: value_type*
const_pointer allocator_traits<allocator_type>::const_pointer for the default allocator: const value_type*
iterator a bidirectional iterator to value_type convertible to const_iterator
const_iterator a bidirectional iterator to const value_type
reverse_iterator reverse_iterator<iterator>
const_reverse_iterator reverse_iterator<const_iterator>
difference_type a signed integral type, identical to: iterator_traits<iterator>::difference_type usually the same as ptrdiff_t
size_type an unsigned integral type that can represent any non-negative value of difference_type usually the same as size_t

在这里插入图片描述

map使用:

构造&析构函数:

//empty (1)	
explicit map (const key_compare& comp = key_compare(),
              const allocator_type& alloc = allocator_type());
explicit map (const allocator_type& alloc);

//range (2)	
template <class InputIterator>
  map (InputIterator first, InputIterator last,
       const key_compare& comp = key_compare(),
       const allocator_type& = allocator_type());

//copy (3)	
map (const map& x);
map (const map& x, const allocator_type& alloc);

//move (4)	
map (map&& x);
map (map&& x, const allocator_type& alloc);

//initializer list (5)	
map (initializer_list<value_type> il,
     const key_compare& comp = key_compare(),
     const allocator_type& alloc = allocator_type());


~map();


//copy (1)	
map& operator= (const map& x);

//move (2)	
map& operator= (map&& x);

//initializer list (3)	
map& operator= (initializer_list<value_type> il);

元素访问函数:

      iterator begin() noexcept;
const_iterator begin() const noexcept;

      iterator end() noexcept;
const_iterator end() const noexcept;

      reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;

      reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;

const_iterator cbegin() const noexcept;

const_iterator cend() const noexcept;

const_reverse_iterator crbegin() const noexcept;

const_reverse_iterator crend() const noexcept;
//****************************

mapped_type& operator[] (const key_type& k);
mapped_type& operator[] (key_type&& k);

      mapped_type& at (const key_type& k);
const mapped_type& at (const key_type& k) const;

容量函数:

bool empty() const noexcept;

size_type size() const noexcept;

size_type max_size() const noexcept;

元素修改函数:

//single element (1)	
pair<iterator,bool> insert (const value_type& val);
template <class P> pair<iterator,bool> insert (P&& val);

//with hint (2)	
iterator insert (const_iterator position, const value_type& val);
template <class P> iterator insert (const_iterator position, P&& val);

//range (3)	
template <class InputIterator>
  void insert (InputIterator first, InputIterator last);

//initializer list (4)	
void insert (initializer_list<value_type> il);
//************************

//(1)	
iterator  erase (const_iterator position);
//(2)	
size_type erase (const key_type& k);
//(3)	
iterator  erase (const_iterator first, const_iterator last);
//************************

void swap (map& x);
//************************

void clear() noexcept;
//************************

template <class... Args>
  pair<iterator,bool> emplace (Args&&... args);
//************************

template <class... Args>
  iterator emplace_hint (const_iterator position, Args&&... args);
//************************

操作系列:

      iterator find (const key_type& k);
const_iterator find (const key_type& k) const;


size_type count (const key_type& k) const;


      iterator lower_bound (const key_type& k);
const_iterator lower_bound (const key_type& k) const;


      iterator upper_bound (const key_type& k);
const_iterator upper_bound (const key_type& k) const;


pair<const_iterator,const_iterator> equal_range (const key_type& k) const;
pair<iterator,iterator>             equal_range (const key_type& k);

分配器系列:

allocator_type get_allocator() const noexcept;

multimap:

template < class Key,                                     // multimap::key_type
           class T,                                       // multimap::mapped_type
           class Compare = less<Key>,                     // multimap::key_compare
           class Alloc = allocator<pair<const Key,T> >    // multimap::allocator_type
           > class multimap;

multimap特性:

  • 内部所有的数据都是有序的

  • 底层为红黑树

  • 元素允许重复

  • 不支持[] 和 at() 元素访问

  • 其他和map相同

multimap使用:

基本上和map相同, 就是没有at() & operator[]

这里就不进行重复记录了

set:

template < class T,                        // set::key_type/value_type
           class Compare = less<T>,        // set::key_compare/value_compare
           class Alloc = allocator<T>      // set::allocator_type
           > class set;

set特性:

set与map的区别就是:

  • 所有的元素没有value, 只有Key
  • 不支持map的下标访问

其余的和map都相同:

  • 底层实现为红黑树
  • 不允许出现键值重复
  • 所有的元素都会被自动排序
  • 不能通过迭代器来改变set的值,因为set的值就是键

成员类型:

member type definition notes
key_type The first template parameter (T)
value_type The first template parameter (T)
key_compare The second template parameter (Compare) defaults to: less
value_compare The second template parameter (Compare) defaults to: less
allocator_type The third template parameter (Alloc) defaults to: allocator
reference value_type&
const_reference const value_type&
pointer allocator_traits::pointer for the default allocator: value_type*
const_pointer allocator_traits::const_pointer for the default allocator: const value_type*
iterator a bidirectional iterator to const value_type * convertible to const_iterator
const_iterator a bidirectional iterator to const value_type *
reverse_iterator reverse_iterator *
const_reverse_iterator reverse_iterator *
difference_type a signed integral type, identical to: iterator_traits::difference_type usually the same as ptrdiff_t
size_type an unsigned integral type that can represent any non-negative value of difference_type usually the same as size_t

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yjR1njG7-1579571086304)(C:\Users\Janus II\AppData\Roaming\Typora\typora-user-images\image-20191214104258120.png)]

set使用:

构造与析构:

//empty (1)	
explicit set (const key_compare& comp = key_compare(),
              const allocator_type& alloc = allocator_type());
explicit set (const allocator_type& alloc);

//range (2)	
template <class InputIterator>
  set (InputIterator first, InputIterator last,
       const key_compare& comp = key_compare(),
       const allocator_type& = allocator_type());

//copy (3)	
set (const set& x);
set (const set& x, const allocator_type& alloc);

//move (4)	
set (set&& x);
set (set&& x, const allocator_type& alloc);

//initializer list (5)	
set (initializer_list<value_type> il,
     const key_compare& comp = key_compare(),
     const allocator_type& alloc = allocator_type());


~set();



//copy (1)	
set& operator= (const set& x);

//move (2)	
set& operator= (set&& x);

//initializer list (3)	
set& operator= (initializer_list<value_type> il);

元素访问函数:

      iterator begin() noexcept;
const_iterator begin() const noexcept;

      iterator end() noexcept;
const_iterator end() const noexcept;

      reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;

      reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;

const_iterator cbegin() const noexcept;

const_iterator cend() const noexcept;

const_reverse_iterator crbegin() const noexcept;

const_reverse_iterator crend() const noexcept;


容量函数:

bool empty() const noexcept;

size_type size() const noexcept;

size_type max_size() const;

编辑器:


single element (1)	
pair<iterator,bool> insert (const value_type& val);
pair<iterator,bool> insert (value_type&& val);
with hint (2)	
iterator insert (const_iterator position, const value_type& val);
iterator insert (const_iterator position, value_type&& val);
range (3)	
template <class InputIterator>
  void insert (InputIterator first, InputIterator last);
initializer list (4)	
void insert (initializer_list<value_type> il);


(1)	
iterator  erase (const_iterator position);
(2)	
size_type erase (const value_type& val);
(3)	
iterator  erase (const_iterator first, const_iterator last);


void swap (set& x);


void clear() noexcept;


template <class... Args>
  pair<iterator,bool> emplace (Args&&... args);


template <class... Args>
  iterator emplace_hint (const_iterator position, Args&&... args);

Observers:

key_compare key_comp() const;

value_compare value_comp() const;

operations操作函数:

const_iterator find (const value_type& val) const;
iterator       find (const value_type& val);


size_type count (const value_type& val) const;


      iterator lower_bound (const value_type& val);
const_iterator lower_bound (const value_type& val) const;


      iterator upper_bound (const value_type& val);
const_iterator upper_bound (const value_type& val) const;


pair<const_iterator,const_iterator> equal_range (const value_type& val) const;
pair<iterator,iterator>             equal_range (const value_type& val);

allocator分配器:

allocator_type get_allocator() const noexcept;

multiset:

template < class T,                        // multiset::key_type/value_type
           class Compare = less<T>,        // multiset::key_compare/value_compare
           class Alloc = allocator<T> >    // multiset::allocator_type
           > class multiset;

multiset特性:

函数与set基本一致, 这里不做重复记录

无序关联容器:

unordered_map:

template < class Key,                                    // unordered_map::key_type
           class T,                                      // unordered_map::mapped_type
           class Hash = hash<Key>,                       // unordered_map::hasher
           class Pred = equal_to<Key>,                   // unordered_map::key_equal
           class Alloc = allocator< pair<const Key,T> >  // unordered_map::allocator_type
           > class unordered_map;

unordered_map特性:

  • 底层是哈希表

    所以元素查找的时间复杂度为O(1)

    实际上底层使用的是一个下标范围比较大的数组来存储元素,形成很多的桶,利用hash函数对key进行映射到不同区域进行保存

    所以与map相比会更占用内存

  • 与map的区别就是元素为无序状态

  • 元素不存在重复, 都是一对一映射

成员类型:

member type definition notes
key_type the first template parameter (Key)
mapped_type the second template parameter (T)
value_type pair
hasher the third template parameter (Hash) defaults to: hash
key_equal the fourth template parameter (Pred) defaults to: equal_to
allocator_type the fifth template parameter (Alloc) defaults to: allocator
reference Alloc::reference
const_reference Alloc::const_reference
pointer Alloc::pointer for the default allocator: value_type*
const_pointer Alloc::const_pointer for the default allocator: const value_type*
iterator a forward iterator to value_type
const_iterator a forward iterator to const value_type
local_iterator a forward iterator to value_type
const_local_iterator a forward iterator to const value_type
size_type an unsigned integral type usually the same as size_t
difference_type a signed integral type usually the same as ptrdiff_t

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aBtWDX8F-1579571086305)(C:\Users\Janus II\AppData\Roaming\Typora\typora-user-images\image-20191214104230261.png)]

unordered_map使用:

构造与析构:

//empty (1)	
explicit unordered_map ( size_type n = /* see below */,
                         const hasher& hf = hasher(),
                         const key_equal& eql = key_equal(),
                         const allocator_type& alloc = allocator_type() );
explicit unordered_map ( const allocator_type& alloc );

//range (2)	
template <class InputIterator>
  unordered_map ( InputIterator first, InputIterator last,
                  size_type n = /* see below */,
                  const hasher& hf = hasher(),
                  const key_equal& eql = key_equal(),
                  const allocator_type& alloc = allocator_type() );

//copy (3)	
unordered_map ( const unordered_map& ump );
unordered_map ( const unordered_map& ump, const allocator_type& alloc );

//move (4)	
unordered_map ( unordered_map&& ump );
unordered_map ( unordered_map&& ump, const allocator_type& alloc );

//initializer list (5)	
unordered_map ( initializer_list<value_type> il,
                size_type n = /* see below */,
                const hasher& hf = hasher(),
                const key_equal& eql = key_equal(),
                const allocator_type& alloc = allocator_type() );


~unordered_map();


//copy (1)	
unordered_map& operator= ( const unordered_map& ump );

//move (2)	
unordered_map& operator= ( unordered_map&& ump );

//initializer list (3)	
unordered_map& operator= ( intitializer_list<value_type> il );

Capacity容器函数:

bool empty() const noexcept;

size_type size() const noexcept;

size_type max_size() const noexcept;

iterator迭代器:

container iterator (1)	
      iterator begin() noexcept;
const_iterator begin() const noexcept;

bucket iterator (2)	
      local_iterator begin ( size_type n );
const_local_iterator begin ( size_type n ) const;


container iterator (1)	
      iterator end() noexcept;
const_iterator end() const noexcept;

bucket iterator (2)	
      local_iterator end (size_type n);
const_local_iterator end (size_type n) const;


container iterator (1)	
const_iterator cbegin() const noexcept;

bucket iterator (2)	
const_local_iterator cbegin ( size_type n ) const;


container iterator (1)	
const_iterator cend() const noexcept;

bucket iterator (2)	
const_local_iterator cend ( size_type n ) const;

Element access 元素访问:

mapped_type& operator[] ( const key_type& k );
mapped_type& operator[] ( key_type&& k );

mapped_type& at ( const key_type& k );
const mapped_type& at ( const key_type& k ) const;

Element lookup 元素查找:

      iterator find ( const key_type& k );
const_iterator find ( const key_type& k ) const;


size_type count ( const key_type& k ) const;


pair<iterator,iterator>
   equal_range ( const key_type& k );
pair<const_iterator,const_iterator>
   equal_range ( const key_type& k ) const;

Modifiers 编辑器:

template <class... Args>
pair<iterator, bool> emplace ( Args&&... args );


template <class... Args>
iterator emplace_hint ( const_iterator position, Args&&... args );


//(1)	
pair<iterator,bool> insert ( const value_type& val );
//(2)	
template <class P>
    pair<iterator,bool> insert ( P&& val );
//(3)	
iterator insert ( const_iterator hint, const value_type& val );
//(4)	
template <class P>
    iterator insert ( const_iterator hint, P&& val );
//(5)	
template <class InputIterator>
    void insert ( InputIterator first, InputIterator last );
//(6)	
void insert ( initializer_list<value_type> il );


by position (1)	
iterator erase ( const_iterator position );
by key (2)	
size_type erase ( const key_type& k );
range (3)	
iterator erase ( const_iterator first, const_iterator last );


void clear() noexcept;


void swap ( unordered_map& ump );

Buckets

size_type bucket_count() const noexcept;

size_type max_bucket_count() const noexcept;

size_type bucket_size ( size_type n ) const;

size_type bucket ( const key_type& k ) const;

Hash policy 哈希策略:

float load_factor() const noexcept;

get (1)	
float max_load_factor() const noexcept;
set (2)	
void max_load_factor ( float z );

void rehash( size_type n );

void reserve ( size_type n );

Observers 观察函数:

hasher hash_function() const;

key_equal key_eq() const;

allocator_type get_allocator() const noexcept;

Non-member function overloads:

equality (1)	
template <class Key, class T, class Hash, class Pred, class Alloc>
  bool operator== ( const unordered_map<Key,T,Hash,Pred,Alloc>& lhs,
                    const unordered_map<Key,T,Hash,Pred,Alloc>& rhs );
inequality (2)	
template <class Key, class T, class Hash, class Pred, class Alloc>
  bool operator!= ( const unordered_map<Key,T,Hash,Pred,Alloc>& lhs,
                    const unordered_map<Key,T,Hash,Pred,Alloc>& rhs );


template <class Key, class T, class Hash, class Pred, class Alloc>
  void swap ( unordered_map<Key,T,Hash,Pred,Alloc>& lhs,
              unordered_map<Key,T,Hash,Pred,Alloc>& rhs );

unordered_multimap:

template < class Key,                                    // unordered_multimap::key_type
           class T,                                      // unordered_multimap::mapped_type
           class Hash = hash<Key>,                       // unordered_multimap::hasher
           class Pred = equal_to<Key>,                   // unordered_multimap::key_equal
           class Alloc = allocator< pair<const Key,T> >  // unordered_multimap::allocator_type
           > class unordered_multimap;

unordered_multimap特性:

  • 底层是哈希表

    所以**元素查找的时间复杂度为o(1)

  • 与multimap的区别就是元素为无序状态

  • 元素允许重复

unordered_multimap使用:

基本上和unordered_map相同, 但是少了成员访问的at() 和operator[] 

unordered_set:

template < class Key,                        // unordered_set::key_type/value_type
           class Hash = hash<Key>,           // unordered_set::hasher
           class Pred = equal_to<Key>,       // unordered_set::key_equal
           class Alloc = allocator<Key>      // unordered_set::allocator_type
           > class unordered_set;

unordered_set特性:

  • 底层是哈希表

    所以元素查找的时间复杂度为O(1)

    实际上底层使用的是一个下标范围比较大的数组来存储元素,形成很多的桶,利用hash函数对key进行映射到不同区域进行保存

    所以与set相比会更占用内存

  • 与set的区别就是元素为无序状态

  • 元素不存在重复, 都是一对一映射

unordered_multiset:

template < class Key,                         // unordered_multiset::key_type/value_type
           class Hash = hash<Key>,            // unordered_multiset::hasher
           class Pred = equal_to<Key>,        // unordered_multiset::key_equal
           class Alloc = allocator<Key>       // unordered_multiset::allocator_type
           > class unordered_multiset;

unordered_multiset特性:

 和unordered_set完全相同 

ltimap:

template < class Key,                                    // unordered_multimap::key_type
           class T,                                      // unordered_multimap::mapped_type
           class Hash = hash<Key>,                       // unordered_multimap::hasher
           class Pred = equal_to<Key>,                   // unordered_multimap::key_equal
           class Alloc = allocator< pair<const Key,T> >  // unordered_multimap::allocator_type
           > class unordered_multimap;

unordered_multimap特性:

  • 底层是哈希表

    所以**元素查找的时间复杂度为o(1)

  • 与multimap的区别就是元素为无序状态

  • 元素允许重复

unordered_multimap使用:

基本上和unordered_map相同, 但是少了成员访问的at() 和operator[] 

unordered_set:

template < class Key,                        // unordered_set::key_type/value_type
           class Hash = hash<Key>,           // unordered_set::hasher
           class Pred = equal_to<Key>,       // unordered_set::key_equal
           class Alloc = allocator<Key>      // unordered_set::allocator_type
           > class unordered_set;

unordered_set特性:

  • 底层是哈希表

    所以元素查找的时间复杂度为O(1)

    实际上底层使用的是一个下标范围比较大的数组来存储元素,形成很多的桶,利用hash函数对key进行映射到不同区域进行保存

    所以与set相比会更占用内存

  • 与set的区别就是元素为无序状态

  • 元素不存在重复, 都是一对一映射

unordered_multiset:

template < class Key,                         // unordered_multiset::key_type/value_type
           class Hash = hash<Key>,            // unordered_multiset::hasher
           class Pred = equal_to<Key>,        // unordered_multiset::key_equal
           class Alloc = allocator<Key>       // unordered_multiset::allocator_type
           > class unordered_multiset;

unordered_multiset特性:

 和unordered_set完全相同 

发布了17 篇原创文章 · 获赞 7 · 访问量 1344

猜你喜欢

转载自blog.csdn.net/qq_42683011/article/details/104058805