STL容器的基础应用

STL容器的基础应用

STL容器分类树状图
注:本文中所有可选参数(包括可选模板参数、可选构造函数参数)均在其之后标注*

STL容器做形参时,默认情况下仍为按值传递。若需按址传递,可在形参中传递STL容器的引用,或使用指向STL容器的指针,或使用模板参数推导结合传引用。

序列容器

序列容器可接受的数据类型有基类型、序列容器类型(多维序列容器的实现方法之一)、复合类型(pair、tuple等)、自定义数据类型(struct、union等)、指针类型(包括函数指针)等。

同时,序列元素本身可以作为数组元素(多维序列容器另一实现方法)。高维序列容器在此仅用vector进行举例,其余序列容器同理。

vector 动态数组

  • 支持随机访问
  • 具有begin、end迭代器
  • 在等长度的数组中,所占内存大小:vector>array==C数组
  • vector的属性:size:实际大小;capacity:容量,即为预分配大小(注:访问超过实际大小的预分配内存部分为未定义行为)

一维vector

  • 定义:vector<数据类型>类名。默认size=0,capacity由编译器决定,O(1)
  • 构造函数:
    • 传入size及数据:vector<数据类型>类名(size,data*),实际大小为size,每个元素都为data,data数据类型必须与vector模板参数中的数据类型相同,若不指定data则默认每个data为0。O( n n n)
    • 传入其他同维vector类名:vector<数据类型>类名(其他类名),O( n n n)
    • 传入其他vector或非vector序列容器(包括C数组)的迭代器或指针:vector<数据类型>类名(迭代器1/指针基址,迭代器2/尾指针),O( n n n)或O( n log ⁡ n n\log n nlogn)
      注:若传入不同维的vector,仅支持将低维vector传递给高维vector,且仅支持复制size和capacity,value无法复制;若反向传递则不允许。
  • 初始化:
    • 以序列表形式初始化:vector<数据类型>类名{...}vector<数据类型>={...},O( n n n)
    • 以其他同维vector初始化:vector<数据类型>类名=其他类名,O( n n n)

二维vector

数据类型为vector
  • 定义:vector<vector<数据类型>>类名,O(1)

  • 构造函数:

    • 传入size及数据:vector<vector<数据类型>>类名(size,data*),实际大小为size,每个元素都为data,data必须与最外层vector模板参数中所指定的类型相同(在此处即必须为vector<数据类型>),若不指定data则默认每个data为vector<数据类型>,即每个data为size=0,data=0的一维vector)。data中的vector支持构造函数。O( m ∗ n m*n mn)
      例:vector<vector<int>>v(3,vector<int>(5,4)):创建一个3行5列,每个元素为4的二维vector
    • 传入其他同维vector类名:vector<vector<数据类型>>类名(其他类名),O( m ∗ n m*n mn)
    • 传入其他vector迭代器:vector<vector<数据类型>>类名(迭代器1,迭代器2),O( m ∗ n m*n mn)
      注:若传入不同维的vector,仅支持将低维vector传递给高维vector,且仅支持复制size和capacity,value无法复制;若反向传递则不允许;二维及更高维vector不支持传入其他非vector序列容器及C数组
  • 初始化:

    • 以序列表形式初始化:vector<vector<数据类型>>类名{{...},{...},...}vector<vector<数据类型>>类名={{...},{...},...},O( m ∗ n m*n mn)
    • 以其他同维vector初始化:vector<vector<数据类型>>类名=其他类名`,O( m ∗ n m*n mn)
  • 可采用每次push_back一维数组的方式完成输入

vector数组
  • 定义:vector<int>类名[大小],O(1)
  • vector数组无法使用构造函数

vector的常用成员函数

成员函数功能复杂度
运算符[下标]随机访问元素O(1)
类名.at(下标)随机访问元素(有越界检查)O(1)
类名.front()访问首元素O(1)
类名.back()访问末元素O(1)
类名.data()访问基址(当size!=0时,否则为NULL)O(1)
类名.push_back()向容器末尾插入元素O(1)
类名.pop_back()弹出容器末尾元素O(1)
类名.size()获取size(实际长度)O(1)
类名.empty()判断size是否为0O(1)
类名.capacity()获取capacity(预分配内存)O(1)
类名.erase(迭代器1,迭代器2*)擦除某个或某个区间的元素(真删除),常与std::remove结合使用(移除-擦除惯用法)O( n n n)
类名.insert(迭代器,数量*,元素)
类名.insert(目标迭代器,来源迭代器1,来源迭代器2)
在该位置插入指定数量的某元素
在目标处插入来源区间内的元素
O( n n n)
O( m + n m+n m+n)
类名.clear()清空容器为size==0,capacity不变O( n n n)
类名.resize(个数,数据*)修改容器的size:原容器size==个数,无操作;原容器size>个数,将size减小到个数,原有数据不变;原容器size<个数,原有数据不变,新增部分设为指定数据(默认为0)O( n n n)
类名.reserve(值)增加capacity到新值(增加预分配内存)O( n n n)
类名.shrink_to_fit()减小capacity的值,修改为与size相同(释放预分配内存)O( n n n)
类名.assign(个数,元素)
类名.assign(来源迭代器1,来源迭代器2)
将指定个数的元素值或将某个区间内的值分配给容器,容器原有内容被覆盖。O( n n n)
类名.swap(其他类名)交换两数组容器,比std::swap(O( n n n))更优秀O(1)

补充:一些其他常与STL容器结合使用的函数

函数功能复杂度
fill(迭代器1,迭代器2,数据)填充容器O( n n n)
remove(迭代器1,迭代器2,数据)移除某个区间内的某元素,不改变size大小的“假删除”。将区间内非此数据的元素向前移动。返回值为冗余区首个元素的迭代器,常与erase结合使用(移除-擦除惯用法)O( n n n)
unique(迭代器1,迭代器2)移除某个区间内重复元素,不改变size大小的“假删除”。将区间内非重复元素向前移动,将重复元素的首个元素向前移动。返回值为冗余区首个元素的迭代器,常与erase结合使用O( n n n)
reverse(迭代器1,迭代器2)反转容器元素顺序O( n n n)
find(迭代器1,迭代器2,值)在区间内寻找某值。若找到,返回值为迭代器,否则返回end迭代器O( n n n)
max(值1,值2)max({...})
min(值1,值2)min({...})
返回两个元素/序列表中元素的最大(小)值O(1)
O( n n n)
max_element(迭代器1,迭代器2)
min_element(迭代器1,迭代器2)
返回区间内最大(小)值元素的迭代器O( n n n)
sort(迭代器1,迭代器2,cmp*)对区间内元素进行排序,默认为升序
比较规则:std::greater<>()(前一个>后一个,降序)或std::less<>()(前一个<后一个,升序);若自定义cmp函数,则也遵循此规则
O( n log ⁡ n n\log n nlogn)
binary_search(迭代器1,迭代器2,key,cmp*)有序序列中二分查找某元素,若存在返回1,不存在返回0,cmp默认为升序O( n log ⁡ n n\log n nlogn)
upper_bound(迭代器1,迭代器2,key,cmp*)有序序列中二分查找首个>(严格大于)key的元素,查找成功返回其迭代器,否则返回end迭代器,cmp默认为升序O( n log ⁡ n n\log n nlogn)
lower_bound(迭代器1,迭代器2,key,cmp*)有序序列中二分查找首个 ≥ \ge (大于等于)key的元素,查找成功返回其迭代器,否则返回end迭代器,cmp默认为升序O( n log ⁡ n n\log n nlogn)
next_permutation(迭代器1,迭代器2,cmp*)若序列有下一个字典序排列组合,则在原序列中改变顺序,返回值为1;否则返回0
常与do-while循环使用
O ( n ) O(n) O(n)
prev_permutation(迭代器1,迭代器2,cmp*)若序列有上一个字典序排列组合,则在原序列中改变顺序,返回值为1;否则返回0
常与do-while循环使用
O ( n ) O(n) O(n)

deque 双端队列

  • 支持随机访问
  • 有begin、end迭代器
  • 仅有size属性,没有capacity属性
  • 定义:deque<数据类型>类名,O(1)
  • 构造函数:
    • 传入size及数据:deque<数据类型>类名(size,data*),O( n n n)
    • 传入其他同维deque类名:deque<数据类型>类名(其他类名),O( n n n)
    • 传入其他deque或非deque序列容器(包括C数组)的迭代器或指针:deque<数据类型>类名(迭代器1/指针基址,迭代器2/尾指针),O( n n n)
      注:若传入不同维的vector,仅支持将低维deque传递给高维deque,且仅支持复制size,value无法复制;若反向传递则不允许。
  • 初始化:
    • 以序列表形式初始化:deque<数据类型>类名{...}deque<数据类型>={...},O( n n n)
    • 以其他同维deque初始化:deque<数据类型>类名=其他类名,O( n n n)
成员函数功能复杂度
运算符[下标]随机访问O(1)
类名.at(下标)带有越界检查的随机访问O(1)
类名.front()访问队头元素O(1)
类名.back()访问队尾元素O(1)
类名.push_front()在队头插入元素O(1)
类名.push_back()在队尾插入元素O(1)
类名.pop_front()弹出队头元素O(1)
类名.pop_back()弹出队尾元素O(1)
类名.insert(迭代器,数量*,元素)
类名.insert(目标迭代器,来源迭代器1,来源迭代器2)
在该位置插入指定数量的某元素
在目标处插入来源区间内的元素
O( n n n)
O( m + n m+n m+n)
类名.size()获取sizeO(1)
类名.empty()判断size是否为0O(1)
类名.erase(迭代器1,迭代器2*)擦除某个或某个区间的元素(真删除),常与std::remove结合使用(移除-擦除惯用法)O( n n n)
类名.resize(个数,数据*)修改容器的size:原容器size==个数,无操作;原容器size>个数,将size减小到个数,原有数据不变;原容器size<个数,原有数据不变,新增部分设为指定数据(默认为0)O( n n n)
类名.clear()清空容器为size==0O( n n n)
类名.swap(其他类名)交换两数组容器,比std::swap(O( n n n))更优秀O(1)
类名.assign(个数,元素)
类名.assign(来源迭代器1,来源迭代器2)
将指定个数的元素值或将某个区间内的值分配给容器,容器原有内容被覆盖。O( n n n)

list 双链表

  • 有begin、end迭代器
  • 不支持随机访问
  • 无capacity属性
  • 定义:list<数据类型>类名,O(1)
  • 构造函数:
    • 传入size及data:list<数据类型>类名(size,data*),O( n n n)
    • 传入其他同维list类名:list<数据类型>类名(其他类名),O( n n n)
    • 传入其他list或非list序列容器(包括C数组)的迭代器或指针:list<数据类型>类名(迭代器1/指针基址,迭代器2/尾指针),O( n n n)
      注:若传入不同维的list,仅支持将低维list传递给高维list,且仅支持复制size,value无法复制;若反向传递则不允许。
  • 初始化:
    • 以序列表形式初始化:list<数据类型>类名{...}list<数据类型>={...},O( n n n)
    • 以其他同维list初始化:list<数据类型>类名=其他类名,O( n n n)
成员函数功能复杂度
类名.front()访问头结点O(1)
类名.back()访问尾结点O(1)
类名.push_front()在头结点插入元素O(1)
类名.push_back()在尾结点插入元素O(1)
类名.pop_front()弹出头结点O(1)
类名.pop_back()弹出尾结点O(1)
类名.size()获取sizeO(1)
类名.empty()判断size是否为0O(1)
类名.clear()清空容器为size==0O( n n n)
类名.swap(其他类名)交换两链表容器,比std::swap(O( n n n))更优秀O(1)
类名.assign(个数,元素)
类名.assign(来源迭代器1,来源迭代器2)
将指定个数的元素值或将某个区间内的值分配给容器,容器原有内容被覆盖。O( n n n)
类名.insert(迭代器,数量*,元素)
类名.insert(目标迭代器,来源迭代器1,来源迭代器2)
在该位置插入指定数量的某元素/在目标处插入来源区间内的元素O( n n n)
类名.erase(迭代器1,迭代器2*)擦除某个或某个区间的元素(真删除)O( n n n)
类名.sort(cmp*)对链表进行排序,默认为升序
排序规则:std::greater<>()(降序)或std::less<>()(升序)
O( n log ⁡ n n\log n nlogn)
类名.remove(值)真删除某个元素值(与其他序列容器不同)O( n n n)
类名.merge(其他类名)合并两有序链表O( m + n m+n m+n)
类名.reverse()反转链表O( n n n)
类名.unique()真删除重复元素值(与其他序列容器不同)O( n n n)
类名.splice(目标迭代器,其他类名,来源迭代器1*,来源迭代器2*)将其他链表元素链接到当前链表的目标迭代器处。若无第3和4参数,则为其他链表所有元素均链接;若有第3无4参数,则为其他链表的来源迭代器1处的元素进行链接;若有第3和4参数,则为其他链表的区间元素进行链接O(1)(无3无4或有3无4)
O( n n n)(有3有4)

array 数组

  • 大小必须在编译时确定的字面常量,不能使用变量控制大小(不支持VLC)
  • 无capacity属性
  • 有begin、end迭代器
  • 定义:array<数据类型,大小>类名
  • 无构造函数
  • 初始化:
    • 以序列表形式初始化:array<数据类型,大小>类名{...}array<数据类型,大小>类名={...},O( n n n)
    • 以其他同维list初始化:array<数据类型,大小>类名=其他类名,O( n n n)
成员函数功能复杂度成员函数功能复杂度
运算符[下标]随机访问O(1)类名.size()获取size(实际长度)O(1)
类名.at(下标)带有越界检查的随机访问O(1)类名.empty()判断size是否为0O(1)
类名.front()访问首元素O(1)类名.swap(其他类名)交换两容器O(1)
类名.back()访问末元素O(1)类名.fill(值)以特定值填充容器O( n n n)
类名.data()访问基址(当size!=0时,否则为NULL)O(1)
  • 通过std::get对array进行访问:get<下标>(类名) 下标必须是字面常量,不可以是变量!

补充:bitset 二进制位序列容器

  • 无begin、end迭代器
  • 定义:bitset<size>类名,size为二进制位数,必须为字面常量
  • 补充:计算size: ∀ x > 0 \forall x>0 x>0,size= ⌈ log ⁡ 2 ( x ) ⌉ \lceil\log_2(x)\rceil log2(x)⌉
  • 构造函数:
    • 传入整数:bitset<size>类名(整数)
    • 传入其他全部由数字型字符构成的string/C字符数组/字符串字面常量:bitset<size>类名(其他类名/数组名/常量)(传入内容中不允许包含任何非数字型字符!)
    • 传入其他bitset:bitset<size>类名(其他类名)
  • 初始化:
    • 传入整数:bitset<size>类名{整数}
    • 传入其他全部由数字型字符构成的string/C字符数组/字符串字面常量:bitset<size>类名{其他类名/数组名/常量}(传入内容中不允许包含任何非数字型字符!)
  • bitset容器间可进行位运算
成员函数功能复杂度
运算符[下标]随机访问指定位O(1)
类名.test(下标)随机访问指定位(带越界检查)O(1)
类名.size()返回容器sizeO(1)
类名.any()若任意位为1则返回1,否则返回0
类名.none()若没有位为1则返回1,否则返回0
类名.all()若所有位为1则返回1,否则返回0
类名.set(位)将某位设为1O(1)
类名.reset(位)将某位设为0O(1)
类名.count()统计容器中位为1的位的数量
类名.flip(位)将某位值取反O(1)
类名.to_string()返回数据的字符串表示
类名.to_ulong()返回数据的unsigned long 整数表示
类名.to_ullong()返回数据的unsigned long long整数表示

补充:string

  • 有begin、end迭代器
  • 特殊成员:string::npos,一个整数下标,通常为-1,表示字符串中无效或不存在的位置
  • 支持随机访问
  • 有两个属性:size(实际大小)和capacity(预分配内存)
  • 定义:string 类名,O(1)
  • 构造函数:(注:起始下标必须是整形!)
    • 传入其他string类名:string 类名(其他类名,起始下标*,传入长度*),O( n n n)
    • 传入字符串字面常量:string 类名(字符串字面常量,起始下标*,传入长度*),O( n n n)
    • 传入C风格字符串:string 类名(数组名,起始下标*,传入长度*),O( n n n)
    • 传入指定数量的字符:string 类名(数量,字符字面常量),可传入ASCII码,O( n n n)
    • 传入其他string或序列容器的迭代器:string(迭代器1,迭代器2),O( n n n)
  • 初始化:
    • 以其他string类名初始化:string 类名=其他类名,O( n n n)
    • 以字符串字面常量进行初始化:string 类名="字符串字面常量"string 类名{"字符串字面常量"},O( n n n)
    • 以字符字面常量进行初始化:string 类名{'常量1','常量2',...},O( n n n)
  • 字符串的输入:cin(遇到空格或换行停止)、getline(cin,类名)(读取整行)
  • 字符串的转换:to_string:转换为string;stoi/stol/stoll/stof/stod/stold:将string转换为int/long/long long/float/double/long double
  • 字符串流(<sstream>):三种类:istringstream(字符串输入流)、ostringstream(字符串输出流)和stringstream(字符串输入输出流,向下兼容C),支持通过插入器(<<)和析取器(>>)对流进行操作
成员函数功能复杂度
运算符[下标]随机访问O(1)
类名.at(下标)随机访问(带越界检查)O(1)
类名.data()访问基址(当size!=0时,否则为NULL)O(1)
类名.front()访问首元素O(1)
类名.back()访问末元素O(1)
类名.push_back(数据)向容器末尾插入元素O(1)
类名.pop_back()弹出容器末尾元素O(1)
类名.size()
类名.length()
获取string的size(不会被\0截断)O(1)
类名.capacity()获取string的capacityO(1)
类名.empty()检查string是否为空O(1)
类名.clear()清除stringO( n n n)
类名.reserve(值)增加capacity到指定值O( n n n)
类名.resize(值)修改容器的size:原容器size==个数,无操作;原容器size>个数,将size减小到个数,原有数据不变;原容器size<个数,原有数据不变,新增部分设为指定数据(默认为0)O( n n n)
类名.shrink_to_fit()减小capacity的值,修改为与size相同(释放预分配内存)O( n n n)
运算符+=类名/C字符数组/字符/字符序列表/字面常量类名.append(类名,起始下标*,长度*)/类名.append(C字符数组,长度*)/类名.append(字符,数量)/类名.append(迭代器1,迭代器2)/类名.append(字符序列表)字符串连接O( n n n)
运算符+连接两字符串O( m + n m+n m+n)
类名.insert(目标下标,来源字符串*,长度*)/类名.insert(目标下标,C字符数组,长度*)/类名.insert(目标下标/迭代器,长度*,字符)/类名.insert(目标迭代器,来源迭代器1,来源迭代器2)/类名.insert(目标迭代器,序列表)插入元素O( n n n)
类名.erase(起始下标*,长度*)/类名.erase(迭代器)/类名.erase(迭代器1,迭代器2)擦除某个或某个区间的元素(真删除)O( n n n)
类名.replace(目标起始下标,替换长度,来源字符串,来源起始下标*,来源长度*)/类名.replace(目标迭代器1,目标迭代器2,来源字符串)/类名.replace(目标起始下标/目标迭代器1,替换长度/目标迭代器2,来源C字符数组,来源长度*)/类名.replace(目标下标/目标迭代器1,替换长度/目标迭代器2,数量,字符)/类名.replace(目标迭代器1,目标迭代器2,来源迭代器1,来源迭代器2)/类名.replace(目标迭代器1,目标迭代器2,字符序列表)替换字符串中的某部分O( n n n)
类名.swap(其他类名)交换两字符串O(1)
类名.c_str()返回该字符串字符常量指针O(1)
类名.copy(目标C字符数组,数量,起始位置)将该string中的内容复制到目标字符数组中O( n n n)
类名.find(其他类名/字符/C字符数组,起始位置*)/类名.find(C字符数组,起始位置,查找长度)
类名.rfind(其他类名/字符/C字符数组,起始位置*)`/`类名.rfind(C字符数组,起始位置,查找长度)
正/反向查找子串/子字符:若找到返回起始位置迭代器;若未找到,则返回string::nposO( m + n m+n m+n)
类名.find_first_of(其他类名/字符/C字符数组,起始位置*)/类名.find_first_of(C字符数组,起始位置,查找长度)
类名.find_last_of(其他类名/字符/C字符数组,起始位置*)`/`类名.find_last_of(C字符数组,起始位置,查找长度)
类名.find_first_not_of(其他类名/字符/C字符数组,起始位置*)/类名.find_first_not_of(C字符数组,起始位置,查找长度)
类名.find_last_not_of(其他类名/字符/C字符数组,起始位置*)`/`类名.find_last_not_of(C字符数组,起始位置,查找长度)
正向查找首/末个是/不是该子串/字符:若找到返回起始位置迭代器;若未找到,则返回string::nposO( m + n m+n m+n)
类名.substr(起始位置,长度*)生成子串,返回值为新的string对象O( n n n)
类名.compare(当前字符串起始位置*,当前字符串比较长度*,被比较字符串/C字符数组)/类名.compare(当前字符串起始位置,当前字符串比较长度,被比较字符串,被比较字符串起始位置,被比较长度*)/类名.compare(当前字符串起始位置,当前字符串比较长度,被比较C字符数组,被比较长度)比较字符串:若当前字符串<被比较字符串,返回负数;当前字符串==被比较字符串,返回0;当前字符串>被比较字符串,返回正数O( m + n m+n m+n)

容器适配器

底层容器:表示用于实现该STL容器所基于何种底层容器。手动指定时,必须为序列容器(vector、deque、list、array等)。

stack 栈

  • 定义:stack<数据类型,底层容器*>类名,默认底层容器类型为deque,可接受的数据类型与底层容器相同

  • 构造函数:

    • 传入另一stack容器:stack<数据类型,底层容器*>类名(其他类名),不支持传入其他非stack容器,O(1)
    • 传入序列容器的迭代器:仅C++23及之后支持,O( n n n)
  • 不支持使用序列表初始化

  • beginend迭代器,因此无法使用find、unique等函数

  • 可作为数组元素

成员函数功能复杂度成员函数功能复杂度
类名.push(数据)入栈O(1)类名.empty()判断栈是否为空O(1)
类名.pop()出栈O(1)类名.size()获取栈中元素个数O(1)
类名.top()读栈顶元素O(1)类名.swap(其他类名)交换两栈容器O(1)
  • swap成员函数相比于std::swap(O( n n n))更优秀

  • 无清空容器的成员函数,需用while循环+pop函数实现清空,O( n n n)

queue 队列

  • 定义:queue<数据类型,底层容器*>类名,默认底层容器类型为deque,可接受的数据类型与底层容器相同

  • 构造函数:

    • 传入另一queue容器:queue<数据类型,底层容器*>类名(其他类名),不支持传入其他非queue容器,O(1)
    • 传入序列容器的迭代器:仅C++23及之后支持,O( n n n)
  • 不支持使用序列表初始化

  • beginend迭代器,因此无法使用find、unique等函数

  • 可作为数组元素

成员函数功能复杂度成员函数功能复杂度
类名.push(数据)入队O(1)类名.size()获取队列元素个数O(1)
类名.pop()出队O(1)类名.empty()判断队列是否为空O(1)
类名.front()读队头元素O(1)类名.swap(其他类名)交换两队列容器O(1)
类名.back()读队尾元素O(1)
  • swap成员函数相比于std::swap(O( n n n))更优秀
  • 无清空容器的成员函数,需用while循环+pop方法实现清空,O( n n n)

priority_queue 优先队列(二叉堆)

  • 定义:priority_queue<数据类型,底层容器*,优先规则*>类名,默认底层容器为vector,可接受的数据类型与底层容器相同。默认优先规则为less<>(大根堆)。若使用优先规则,则底层容器必须指定。

  • 优先规则:

    • greater<>less<>greater<>表示前>后,在二叉堆中指子节点>父节点,因此创建小根堆;less<>表示前<后,在二叉堆中指子节点<父节点,因此创建大根堆。注意不要与greater<>()less<>()混淆。
    • 自定义函数:在做优先规则时使用std::function<>priority_queue<数据类型,底层容器,function<返回值类型(形参表)>>类名(函数名)
  • 构造函数:

    • 传入序列容器的迭代器:priority_queue<数据类型,底层容器*,优先规则*>类名(迭代器1,迭代器2),O( n n n)或O( m + n m+n m+n)
    • 传入其他priority_queue:priority_queue<数据类型,底层容器*,优先规则*>类名(其他类名),O(1)
  • 不支持使用序列表初始化

  • beginend迭代器,因此无法使用find、unique等函数

  • 可作为数组元素

成员函数功能复杂度成员函数功能复杂度
类名.push(数据)在堆底插入数据O( log ⁡ n \log n logn)类名.size()获取堆中元素个数O(1)
类名.pop()弹出堆顶元素O( log ⁡ n \log n logn)类名.empty()判断堆是否为空O(1)
类名.top()读堆顶元素O(1)类名.swap(其他类名)交换两优先队列容器O(1)
  • swap成员函数相比于std::swap(O( n n n))更优秀
  • 无清空容器的成员函数,需用while循环+pop方法实现清空,O( n log ⁡ n n\log n nlogn)

关联容器

补充:复合结构类型 pair、tuple

pair 对组

批量组织一对数据类型(可接受的数据类型有基类型、序列容器类型、复合类型(pair、tuple等)、自定义数据类型(struct、union等)、指针类型(包括函数指针)等。)

  • 定义:pair<value1数据类型,value2数据类型>类名
  • 构造函数:pair<value1数据类型,value2数据类型>类名(value1,value2)
  • make_pair:创建一个pair对象,make_pair(value1,value2)
  • 初始化:pair<value1数据类型,value2数据类型>类名=make_pair(value1,value2)
  • 访问:与struct类似
    • 直接访问:类名.first:访问value1 类名.second:访问value2
    • 通过指针访问:类名->first:访问value1 类名->second:访问value2
    • 通过std::tie解包:tie(接收变量1,接收变量2)=类名,若不想接收某个值,用std::ignore代替
    • 通过std::get访问:get<0>(类名):访问value1,get<1>(类名):访问value2

tuple 元组

批量组织多个数据类型(可接受的数据类型有基类型、序列容器类型、复合类型(pair、tuple等)、自定义数据类型(struct、union等)、指针类型(包括函数指针)等。)

  • 定义:tuple<value1数据类型,value2数据类型,...,value n数据类型>类名
  • 构造函数:tuple<value1数据类型,value2数据类型,...,value n数据类型>类名(value1,value2,...,value n)
  • make_tuple:创建一个tuple对象,make_tuple(value1,value2,...value n)\
  • 初始化:tuple<value1数据类型,value2数据类型,...,value n数据类型>类名=make_tuple(value1,value2,...value n)
  • 访问:
    • 通过std::tie解包:tie(接收变量1,...,接收变量n)=类名,若不想接收某个值,用std::ignore代替
    • 通过std::get访问:get<0>(类名):访问value1,…,get<n>(类名):访问value n+1
  • 拼接元祖:auto 新类名=tuple_cat(类1,类2,...,类n)

set 键集合

set是不重复的key集合

  • 有begin、end迭代器
  • 不支持随机访问
  • 定义:set<类型,排序规则*>类名,默认排序规则为less<>,O(1)
  • 构造函数:
    • 传入其他set类名:set<类型>类名(其他类名),O(1)
    • 传入其他set迭代器:set<类型>类名(迭代器1,迭代器2),O( n log ⁡ n n\log n nlogn)
  • 初始化:
    • 传入其他set类名:set<类型>类名=其他类名,O(1)
    • 以序列表初始化:set<类型>类名{value1,...,value n},O( n n n)
成员函数功能复杂度
类名.empty()检查容器是否为空O(1)
类名.size()返回容器sizeO(1)
类名.clear(key)清空容器O( n n n)
类名.swap(其他类名)交换两容器O(1)
类名.insert(值)
类名.insert(迭代器1,迭代器2)
类名.insert({序列表})
插入某元素/某区间元素O( n n n)
O( n log ⁡ n n\log n nlogn)
类名.erase(值)
类名.erase(迭代器1,迭代器2)
真删除某元素/某区间元素O( n n n)
类名.count(值)查询值出现的次数O( n n n)
类名.find(值)若找到返回对应值的迭代器,否则返回end迭代器O( log ⁡ n \log n logn)
类名.upper_bound(值)查找>(严格大于)值的迭代器,否则返回end迭代器O( log ⁡ n \log n logn)
类名.lower_bound(值)查找 ≥ \ge 值的迭代器,否则返回end迭代器O( log ⁡ n \log n logn)
  • set的遍历:与序列容器相同,支持正向遍历、反向遍历,基于范围的for循环遍历
  • 特殊的set:unordered_set:不自动排序的set;multiset:允许多个重复值的set;unordered_multiset:不自动排序且允许多个重复值的set

map 键值对集合

map是key->value的集合,可用于实现哈希表/字典,其内部采用红黑树实现。map中无重复的key,但value可以重复。

  • 有begin、end迭代器

  • 定义:map<key类型,value类型,排序规则*>类名,默认排序规则为less<>,O(1)

  • 构造函数:

    • 传入其他map类名:map<key类型,value类型>类名(其他类名),O(1)
    • 传入其他map迭代器:map<key类型,value类型>类名(迭代器1,迭代器2),O( n log ⁡ n n\log n nlogn)
  • 初始化:

    • 传入其他map类名:map<key类型,value类型>类名=其他类名,O(1)
    • 以序列表初始化:map<key类型,value类型>类名{make_pair(key1,value1),...,make_pair(key n,value n)}/map<key类型,value类型>类名{{key1,value1},...,{key n,value n}},O( n log ⁡ n n\log n nlogn)
成员函数功能复杂度
运算符[key]随机访问key所指的value,否则返回0O( log ⁡ n \log n logn)
类名.at(key)随机访问(带越界检查)O( log ⁡ n \log n logn)
类名.empty()检查容器是否为空O(1)
类名.size()返回容器sizeO(1)
类名.clear(key)清空容器O( n n n)
类名.insert(pair<类型,类型>(数据,数据))
类名.insert(make_pair(数据,数据))
类名.insert({key,value})
类名.insert(迭代器1,迭代器2)
类名[key]=value
插入元素O( log ⁡ n \log n logn)
O(( n log ⁡ n n\log n nlogn) + n +n +n)
类名.erase(key)
类名.erase(迭代器1,迭代器2*)
真删除当前key或删除某个区间O( n n n)
类名.swap(其他类名)交换两容器O(1)
类名.count(key)查询key出现的次数O( n n n)
类名.find(key)若找到返回对应key的迭代器,否则返回end迭代器O( log ⁡ n \log n logn)
类名.upper_bound(key)查找>(严格大于)key的迭代器,否则返回end迭代器O( log ⁡ n \log n logn)
类名.lower_bound(key)查找 ≥ \ge key的迭代器,否则返回end迭代器O( log ⁡ n \log n logn)
  • map的遍历:与序列容器相同,支持正向遍历、反向遍历(注意使用迭代器->first访问元素);基于范围的for循环遍历(注意使用变量.first访问元素)
  • 特殊的map:unordered_map:不自动排序的map;multimap:允许多个重复key的map;unordered_multimap:不自动排序且允许多个重复key的map;hash_map:自定义hash函数的map
  • 32
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值