文章目录
- To-Do:
- 容器的概述与使用:
- STL 迭代器
- 顺序容器:
- 适配器容器:
- 关联容器:
- 无序关联容器:
To-Do:
- vector倍长的方式
主要是验证与拓展 - list中的所有成员详解
本次只针对期末可能用到的, 箱套充分使用, 需要进一步拓展 - deque进一步了解
- array进一步了解
- 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);
使用注意项:
- 赋值&添加:
采用类似数组下标的方式对vector进行访问, 下标访问的元素必须是已经存在的元素, 所以不可以用下标法进行元素的添加, 只能用来修改以存在的元素 - 访问:
可以使用下标法&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功能的结合
其元素在内存中的分布并不是连续的:
-
由一段一段的定量连续空间构成,第一个区块朝某个方向扩展,最后一个区块朝相反方向扩展;
-
管理这些分段的定量连续空间,维护其整体连续的假象,并提供随机存取的接口;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LZf21t5v-1579571086302)(C:\Users\Janus II\AppData\Roaming\Typora\typora-user-images\image-20191213183341711.png)]
所以, deque具有这些功能:
-
支持随机访问, 但是性能没有vector好
-
支持内部增删操作,但性能不及list
-
首尾两端能快速增删元素
但是, 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完全相同