Lazy loaded image
技术分享
C++ STL简介
00 分钟
2024-11-27
2024-12-1
type
status
date
slug
summary
tags
category
icon
password
comment
😀
2024.11.27 给C++这个部分收尾一下,拖了太久了~主要介绍STL中容器和一些算法
一、array 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 元素访问函数3. 容量相关函数4. 修改器函数5. 非成员函数特性和注意事项使用场景二、std::vector 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 元素访问函数3. 容量相关函数4. 修改器函数5. 与 STL 算法结合使用特性和注意事项使用场景三、std::deque 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 元素访问函数3. 容量相关函数4. 修改器函数5. 与 STL 算法结合使用特性和注意事项使用场景四、std::forward_list 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 元素访问函数4. 修改器函数5. 链表操作6. 与 STL 算法结合使用特性和注意事项使用场景五、std::list 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 元素访问函数4. 修改器函数5. 链表操作6. 与 STL 算法结合使用特性和注意事项使用场景六、std::set 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 元素操作函数4. 查找操作函数5. 比较器6. 与 STL 算法结合使用特性和注意事项使用场景七、std::multiset 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 元素操作函数4. 查找操作函数5. 比较器6. 与 STL 算法结合使用特性和注意事项使用场景八、std::map 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 元素访问函数4. 修改器函数5. 查找操作函数6. 比较器7. 与 STL 算法结合使用特性和注意事项使用场景九、std::multimap 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 修改器函数4. 查找操作函数5. 比较器6. 与 STL 算法结合使用特性和注意事项使用场景十、std::unordered_set 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 修改器函数4. 查找操作函数5. 哈希相关函数6. 与 STL 算法结合使用特性和注意事项使用场景十一、std::unordered_multiset 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 修改器函数4. 查找操作函数5. 哈希相关函数6. 与 STL 算法结合使用特性和注意事项使用场景十二、std::unordered_map 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 元素访问函数4. 修改器函数5. 查找操作函数6. 哈希相关函数7. 与 STL 算法结合使用特性和注意事项使用场景十三、std::unordered_multimap 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 修改器函数4. 查找操作函数5. 哈希相关函数6. 与 STL 算法结合使用特性和注意事项使用场景十四、std::stack 详解基本特点头文件成员函数详解1. 容量相关函数2. 元素访问函数3. 修改器函数4. 不能与 STL 算法直接结合特性和注意事项使用场景十五、std::queue 详解基本特点头文件成员函数详解1. 容量相关函数2. 元素访问函数3. 修改器函数4. 与 STL 算法结合特性和注意事项使用场景十六、std::priority_queue 详解基本特点头文件成员函数详解1. 容量相关函数2. 元素访问函数3. 修改器函数4. 与 STL 算法结合自定义优先级1. 最小堆2. 自定义比较器特性和注意事项使用场景十七、总结对比说明函数支持对比表进一步说明十八、std::bitset详解头文件特点常用成员函数按位操作支持示例代码十九、std::pair详解头文件特点常用成员常用函数示例代码二十、STL中常用算法STL 中常用算法库详解1. 排序算法2. 查找算法3. 修改算法4. 数值计算算法5. 集合操作算法6. 其他通用算法
 

一、array 详解

std::array 是 C++ 标准模板库(STL)中的一个容器,提供了静态大小的数组封装。与传统的 C 风格数组相比,它在类型安全和功能性方面有更大的提升。

基本特点

  • 静态大小std::array 的大小在编译时确定,不能动态调整。
  • 高效性:内部实现是一个 C 风格的数组,性能几乎没有额外开销。
  • 接口丰富:提供了 STL 容器的统一接口,例如迭代器、容量操作、元素访问等。
  • 类型安全:支持类型检查和范围检查(通过 at() 方法)。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
  • rbegin()crbegin():返回反向迭代器指向最后一个元素。
  • rend()crend():返回反向迭代器指向第一个元素之前的位置。
示例:

2. 元素访问函数

  • at(size_t pos):安全访问指定位置的元素,超出范围会抛出 std::out_of_range 异常。
  • operator[]:快速访问指定位置的元素,不检查范围。
  • front():返回第一个元素的引用。
  • back():返回最后一个元素的引用。
  • data():返回指向数组的指针,可以与 C 风格代码兼容。
示例:

3. 容量相关函数

  • size():返回数组的大小。
  • max_size():返回数组的最大大小,通常等于 size()
  • empty():检查容器是否为空。
示例:

4. 修改器函数

  • fill(const T& value):将数组的每个元素设置为指定值。
  • swap(std::array& other):交换两个数组的内容。
示例:

5. 非成员函数

  • std::get<N>(array):访问数组中索引为 N 的元素,编译期检查。
  • 比较运算符:==, !=, <, >, <=, >=
示例:

特性和注意事项

  1. 大小固定std::array 的大小必须在编译时确定,因此适合静态分配的场景。
  1. 与传统数组的区别
      • 提供 STL 接口,方便与其他容器交互。
      • 支持范围检查和标准库功能。
  1. 与动态容器的区别
      • 不支持动态扩展(如 std::vector)。
      • 性能更高,没有动态分配的开销。

使用场景

  • 数组大小在编译时已知且不会改变的场景。
  • 性能要求较高时,std::array 提供了类似 C 风格数组的效率,但安全性更高。
  • 需要与 STL 容器或算法结合使用时。

 

二、std::vector 详解

std::vector 是 C++ 标准模板库中最常用的动态数组容器,支持动态大小调整。与 std::array 不同,std::vector 的大小在运行时可以灵活扩展或收缩。

基本特点

  • 动态大小:支持自动扩展和收缩。
  • 连续内存:存储在一块连续内存中,可与 C 风格数组兼容。
  • 高效访问:提供常数时间复杂度的随机访问(通过下标操作符)。
  • 丰富功能:支持 STL 迭代器、算法、容量管理等功能。
  • 自动管理内存:容器会自动分配和释放内存,避免手动管理。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
  • rbegin()crbegin():返回指向最后一个元素的反向迭代器。
  • rend()crend():返回指向第一个元素之前的反向迭代器。
示例:

2. 元素访问函数

  • at(size_t pos):安全访问指定位置的元素,超出范围抛出异常。
  • operator[]:快速访问指定位置的元素,不检查范围。
  • front():返回第一个元素的引用。
  • back():返回最后一个元素的引用。
  • data():返回指向底层数组的指针。
示例:

3. 容量相关函数

  • size():返回当前元素个数。
  • max_size():返回容器支持的最大元素数量。
  • capacity():返回当前分配的存储容量。
  • empty():检查容器是否为空。
  • reserve(size_t n):预留至少 n 个容量,避免频繁重新分配。
  • shrink_to_fit():释放未使用的内存,减少内存占用。
示例:

4. 修改器函数

  • clear():移除所有元素。
  • insert(iterator pos, value):在指定位置插入元素。
  • insert(iterator pos, count, value):在指定位置插入多个相同元素。
  • erase(iterator pos):删除指定位置的元素。
  • erase(iterator first, iterator last):删除指定范围的元素。
  • push_back(const T& value):在末尾添加元素。
  • emplace_back(args...):在末尾直接构造元素。
  • pop_back():移除末尾元素。
  • resize(size_t n):调整大小,自动填充新元素为默认值。
  • resize(size_t n, const T& value):调整大小,新元素填充为指定值。
  • swap(vector& other):交换两个容器的内容。
示例:

5. 与 STL 算法结合使用

由于 std::vector 提供迭代器接口,可以与 STL 算法无缝结合:

特性和注意事项

  1. 内存管理std::vector 使用动态分配内存,可能会因频繁的扩展导致性能下降。提前使用 reserve() 可优化。
  1. 线程安全性std::vector 不是线程安全的,需要外部同步。
  1. 性能
      • 随机访问时间复杂度为
      • 插入或删除的时间复杂度通常为 ,尤其是中间位置的操作
  1. 与 C 风格数组的兼容:可以通过 data() 函数获得底层数组的指针,与旧代码或 C 库交互。

使用场景

  • 当需要动态调整数组大小时,std::vector 是首选。
  • 适合对随机访问性能有要求的场景。
  • 常用于集合操作、排序、查找和通用数据存储。
 

三、std::deque 详解

std::deque(双端队列)是 C++ 标准模板库中的动态序列容器,与 std::vector 类似,但它在两端的插入和删除操作效率更高。deque 是 “double-ended queue” 的简称。

基本特点

  • 双端操作高效:在两端插入或删除元素的时间复杂度为
  • 动态大小:支持动态扩展和收缩。
  • 非连续内存:不同于 std::vector 的连续存储,std::deque 由多个连续的小块内存组成。
  • 高效访问:随机访问的时间复杂度为 ,但比 std::vector 稍慢。
  • 灵活性:适合频繁在两端插入或删除元素的场景。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
  • rbegin()crbegin():返回反向迭代器,指向最后一个元素。
  • rend()crend():返回反向迭代器,指向第一个元素之前的位置。
示例:

2. 元素访问函数

  • at(size_t pos):安全访问指定位置的元素,超出范围会抛出异常。
  • operator[]:快速访问指定位置的元素,不检查范围。
  • front():返回第一个元素的引用。
  • back():返回最后一个元素的引用。
示例:

3. 容量相关函数

  • size():返回当前元素个数。
  • max_size():返回容器支持的最大元素数量。
  • empty():检查容器是否为空。
  • shrink_to_fit():调整容量,减少内存浪费(实现可能无效,依赖具体标准库)。
示例:

4. 修改器函数

  • clear():移除所有元素。
  • insert(iterator pos, value):在指定位置插入元素。
  • insert(iterator pos, count, value):在指定位置插入多个相同元素。
  • erase(iterator pos):删除指定位置的元素。
  • erase(iterator first, iterator last):删除指定范围的元素。
  • push_back(const T& value):在末尾添加元素。
  • push_front(const T& value):在开头添加元素。
  • emplace_back(args...):在末尾直接构造元素。
  • emplace_front(args...):在开头直接构造元素。
  • pop_back():移除末尾元素。
  • pop_front():移除开头元素。
  • resize(size_t n):调整大小,自动填充新元素为默认值。
  • resize(size_t n, const T& value):调整大小,新元素填充为指定值。
  • swap(deque& other):交换两个容器的内容。
示例:

5. 与 STL 算法结合使用

由于 std::deque 提供迭代器接口,可以与 STL 算法无缝结合:

特性和注意事项

  1. std::vector 的区别
      • std::deque 支持高效的双端操作,适合频繁在两端插入或删除元素的场景。
      • std::vector 在末尾插入和删除时效率更高。
      • std::vector 使用连续内存,适合与低级 C 风格代码兼容;std::deque 使用分块存储。
  1. 性能
      • 随机访问时间复杂度为 ,但通常比 std::vector 略慢。
      • 两端插入或删除操作时间复杂度为
  1. 与 C 风格数组的兼容性
      • std::deque 不支持直接返回底层数组指针(因为其内存分块实现)。

使用场景

  • 当需要频繁在两端插入或删除元素时,例如队列、缓冲区。
  • 随机访问要求不高,但需要灵活扩展容量的场景。
  • 更高效的双端操作要求。
 

四、std::forward_list 详解

std::forward_list 是 C++ 标准模板库中的单向链表容器,提供了一种轻量级的数据结构。与 std::list 不同,它仅支持单向链接,内存开销较低,适合某些特定场景。

基本特点

  • 单向链表:每个节点只存储一个指向下一个节点的指针。
  • 高效插入和删除:在链表头部或已知位置后的插入与删除操作时间复杂度为
  • 轻量级:由于单向链接的特性,相较于双向链表 (std::list),内存开销更小。
  • 不支持随机访问:不能通过索引访问元素,必须使用迭代器进行遍历。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
示例:

2. 容量相关函数

  • empty():检查容器是否为空。
  • max_size():返回容器支持的最大元素数量。
示例:

3. 元素访问函数

std::forward_list 由于是单向链表,不支持直接的随机访问,也没有 at()operator[] 等操作,需通过迭代器访问。
示例:

4. 修改器函数

  • clear():移除所有元素。
  • insert_after(iterator pos, value):在指定位置之后插入一个元素。
  • insert_after(iterator pos, count, value):在指定位置之后插入多个相同元素。
  • erase_after(iterator pos):删除指定位置之后的单个元素。
  • erase_after(iterator first, iterator last):删除指定范围的元素。
  • push_front(const T& value):在链表头部插入一个元素。
  • emplace_front(args...):在链表头部直接构造元素。
  • pop_front():移除链表头部的元素。
  • resize(size_t n):调整大小,自动填充新元素为默认值。
  • resize(size_t n, const T& value):调整大小,新元素填充为指定值。
  • swap(forward_list& other):交换两个链表的内容。
示例:

5. 链表操作

  • merge(forward_list& other):合并两个有序链表,other 变为空。
  • remove(const T& value):删除所有等于指定值的元素。
  • remove_if(predicate):删除满足条件的所有元素。
  • reverse():反转链表中的元素顺序。
  • sort():对链表中的元素排序。
  • unique():移除相邻的重复元素。
示例:

6. 与 STL 算法结合使用

std::forward_list 支持与部分 STL 算法结合,但由于其单向迭代特性,不支持随机访问相关算法:

特性和注意事项

  1. 单向链表特性
      • 插入和删除操作比 std::vectorstd::deque 更高效。
      • 不支持随机访问,所有访问操作都需要通过迭代器完成。
  1. std::list 的区别
      • std::forward_list 是单向链表,内存占用更少。
      • std::list 是双向链表,支持从任意位置的高效插入和删除。
  1. 性能
      • 插入或删除时间复杂度为 ,适用于频繁动态修改的场景。
      • 遍历或查找时间复杂度为 ,不适合需要频繁随机访问的场景。

使用场景

  • 适合需要高效头部插入或删除元素的场景。
  • 适合内存受限但仍需链表特性的应用(例如嵌入式开发)。
  • 适用于对链表操作有需求但不需要双向链表特性的场景。
 

五、std::list 详解

std::list 是 C++ 标准模板库中的双向链表容器。与 std::forward_list 不同,std::list 提供了双向链接的功能,允许从任意位置进行高效插入和删除操作。

基本特点

  • 双向链表:每个节点存储前驱和后继的指针,可以从任意位置向前或向后遍历。
  • 高效的插入和删除:在任意位置插入或删除元素的时间复杂度为
  • 动态大小:支持动态扩展和收缩。
  • 不支持随机访问:不能通过索引访问元素,必须使用迭代器进行遍历。
  • 内存占用较高:由于双向链接的特性,每个节点比 std::forward_list 需要更多的内存。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
  • rbegin()crbegin():返回反向迭代器,指向最后一个元素。
  • rend()crend():返回反向迭代器,指向第一个元素之前的位置。
示例:

2. 容量相关函数

  • size():返回当前元素个数。
  • max_size():返回容器支持的最大元素数量。
  • empty():检查容器是否为空。
示例:

3. 元素访问函数

  • front():返回第一个元素的引用。
  • back():返回最后一个元素的引用。
示例:

4. 修改器函数

  • clear():移除所有元素。
  • insert(iterator pos, value):在指定位置插入元素。
  • insert(iterator pos, count, value):在指定位置插入多个相同元素。
  • erase(iterator pos):删除指定位置的元素。
  • erase(iterator first, iterator last):删除指定范围的元素。
  • push_back(const T& value):在链表末尾插入元素。
  • push_front(const T& value):在链表头部插入元素。
  • emplace_back(args...):在链表末尾直接构造元素。
  • emplace_front(args...):在链表头部直接构造元素。
  • pop_back():移除链表末尾的元素。
  • pop_front():移除链表头部的元素。
  • resize(size_t n):调整大小,自动填充新元素为默认值。
  • resize(size_t n, const T& value):调整大小,新元素填充为指定值。
  • swap(list& other):交换两个链表的内容。
示例:

5. 链表操作

  • merge(list& other):合并两个有序链表,other 变为空。
  • remove(const T& value):删除所有等于指定值的元素。
  • remove_if(predicate):删除满足条件的所有元素。
  • reverse():反转链表中的元素顺序。
  • sort():对链表中的元素排序。
  • unique():移除相邻的重复元素。
示例:

6. 与 STL 算法结合使用

std::list 支持与 STL 算法结合,但由于其链表特性,某些算法可能效率较低:

特性和注意事项

  1. 双向链表特性
      • 插入和删除操作比 std::vectorstd::deque 更高效,尤其是在中间位置。
      • 支持双向遍历,适合需要从两端或中间插入删除的场景。
  1. std::vector 的区别
      • std::list 插入和删除效率高,但随机访问效率低。
      • std::vector 随机访问效率高,但在中间插入和删除效率低。
  1. std::forward_list 的区别
      • std::list 是双向链表,支持从后向前遍历。
      • std::forward_list 是单向链表,更轻量级,但操作有限。

使用场景

  • 当需要频繁在中间插入或删除元素时,std::list 是首选。
  • 适合需要从两端进行操作且随机访问要求较低的场景。
  • 在需要高效排序、合并或反转链表时。
 

六、std::set 详解

std::set 是 C++ 标准模板库中的有序容器,基于红黑树实现,提供高效的元素管理和有序存储。std::set 中的元素是唯一的,自动按顺序排列。

基本特点

  • 元素唯一性std::set 不允许重复元素。
  • 自动排序:元素按特定的比较规则(默认升序)自动排序。
  • 底层实现:基于红黑树,保证常数的插入、删除和查找时间复杂度为
  • 不可直接修改元素值:由于元素位置依赖排序规则,必须先删除旧元素,再插入新值。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
  • rbegin()crbegin():返回反向迭代器,指向最后一个元素。
  • rend()crend():返回反向迭代器,指向第一个元素之前的位置。
示例:

2. 容量相关函数

  • empty():检查容器是否为空。
  • size():返回当前元素个数。
  • max_size():返回容器支持的最大元素数量。
示例:

3. 元素操作函数

  • insert(const T& value):插入元素,返回迭代器和布尔值,布尔值指示是否成功插入。
  • emplace(args...):在容器中直接构造元素。
  • erase(iterator pos):删除指定位置的元素。
  • erase(const T& value):删除指定值的元素,返回删除的元素个数。
  • erase(iterator first, iterator last):删除指定范围内的元素。
  • clear():移除所有元素。
  • swap(set& other):交换两个集合的内容。
示例:

4. 查找操作函数

  • find(const T& value):查找指定值的元素,返回迭代器,若未找到则返回 end()
  • count(const T& value):返回指定值的出现次数(对于 std::set,结果始终为 0 或 1)。
  • lower_bound(const T& value):返回指向第一个不小于 value 的迭代器。
  • upper_bound(const T& value):返回指向第一个大于 value 的迭代器。
  • equal_range(const T& value):返回等于 value 的元素范围(pair<iterator, iterator>)。
示例:

5. 比较器

  • key_comp():返回用于比较键的比较器对象。
  • value_comp():返回用于比较值的比较器对象。
示例:

6. 与 STL 算法结合使用

std::set 提供了迭代器接口,可以与 STL 算法结合:

特性和注意事项

  1. 唯一性
      • 插入重复元素时,insert() 会返回插入失败的状态。
  1. 有序性
      • 默认按升序排列,可通过自定义比较器改变排序规则。
  1. 效率
      • 查找、插入、删除操作的时间复杂度为
      • 不支持随机访问。
  1. 迭代器稳定性
      • 插入和删除操作不会使其他迭代器失效。

使用场景

  • 需要保持元素唯一性并保持有序的场景。
  • 需要高效查找、插入和删除操作时。
  • 适合需要自动排序但无随机访问需求的集合操作。
 

七、std::multiset 详解

std::multiset 是 C++ 标准模板库中的有序容器,与 std::set 类似,但它允许重复元素。std::multiset 同样基于红黑树实现,提供高效的元素管理和有序存储。

基本特点

  • 允许重复元素:与 std::set 不同,std::multiset 允许存储重复的值。
  • 自动排序:元素按特定的比较规则(默认升序)自动排序。
  • 底层实现:基于红黑树,保证常数的插入、删除和查找时间复杂度为
  • 只读元素:元素值不可直接修改,需通过删除再插入实现。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
  • rbegin()crbegin():返回反向迭代器,指向最后一个元素。
  • rend()crend():返回反向迭代器,指向第一个元素之前的位置。
示例:

2. 容量相关函数

  • empty():检查容器是否为空。
  • size():返回当前元素个数。
  • max_size():返回容器支持的最大元素数量。
示例:

3. 元素操作函数

  • insert(const T& value):插入元素,返回指向新插入元素的迭代器。
  • emplace(args...):在容器中直接构造元素。
  • erase(iterator pos):删除指定位置的元素。
  • erase(const T& value):删除所有与值匹配的元素,返回删除的元素个数。
  • erase(iterator first, iterator last):删除指定范围内的元素。
  • clear():移除所有元素。
  • swap(multiset& other):交换两个集合的内容。
示例:

4. 查找操作函数

  • find(const T& value):查找指定值的第一个元素,返回迭代器,若未找到则返回 end()
  • count(const T& value):返回指定值的出现次数。
  • lower_bound(const T& value):返回指向第一个不小于 value 的迭代器。
  • upper_bound(const T& value):返回指向第一个大于 value 的迭代器。
  • equal_range(const T& value):返回等于 value 的元素范围(pair<iterator, iterator>)。
示例:

5. 比较器

  • key_comp():返回用于比较键的比较器对象。
  • value_comp():返回用于比较值的比较器对象。
示例:

6. 与 STL 算法结合使用

std::multiset 提供了迭代器接口,可以与 STL 算法结合:

特性和注意事项

  1. 允许重复性
      • std::multiset 允许多个相同的元素。
      • 插入时,所有重复元素都会按顺序排列。
  1. 有序性
      • 默认按升序排列,可通过自定义比较器改变排序规则。
  1. 效率
      • 查找、插入、删除操作的时间复杂度为
      • 不支持随机访问。
  1. 迭代器稳定性
      • 插入和删除操作不会使其他迭代器失效。

使用场景

  • 需要存储重复元素并保持有序的场景。
  • 高效的插入、删除和查找操作。
  • 适用于计数问题(例如多次出现的元素)。
 

八、std::map 详解

std::map 是 C++ 标准模板库中的有序关联容器,它以键值对 (key-value) 的形式存储数据,键是唯一的,自动按顺序排列。底层实现是红黑树,提供高效的查找、插入和删除操作。

基本特点

  • 键唯一性std::map 不允许重复的键。
  • 自动排序:键按照特定的比较规则(默认升序)自动排序。
  • 键值对存储:每个元素是一个 std::pair,其中 first 是键,second 是值。
  • 高效操作:基于红黑树实现,插入、删除和查找的时间复杂度为
  • 动态大小:容器大小可以动态调整。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
  • rbegin()crbegin():返回反向迭代器,指向最后一个元素。
  • rend()crend():返回反向迭代器,指向第一个元素之前的位置。
示例:

2. 容量相关函数

  • empty():检查容器是否为空。
  • size():返回当前元素个数。
  • max_size():返回容器支持的最大元素数量。
示例:

3. 元素访问函数

  • operator[]:通过键访问或插入元素。如果键不存在,会插入一个默认值。
  • at(const Key& key):通过键安全访问元素,若键不存在则抛出 std::out_of_range 异常。
示例:

4. 修改器函数

  • insert(const pair<Key, T>& value):插入键值对,返回插入结果(成功或失败)。
  • insert_or_assign(key, value):插入或更新键值对。
  • emplace(args...):直接构造键值对。
  • erase(iterator pos):删除指定位置的元素。
  • erase(const Key& key):删除指定键的元素。
  • erase(iterator first, iterator last):删除指定范围内的元素。
  • clear():移除所有元素。
  • swap(map& other):交换两个容器的内容。
示例:

5. 查找操作函数

  • find(const Key& key):查找指定键的元素,返回指向该元素的迭代器,若未找到则返回 end()
  • count(const Key& key):返回指定键的出现次数(对于 std::map,结果始终为 0 或 1)。
  • lower_bound(const Key& key):返回指向第一个不小于 key 的迭代器。
  • upper_bound(const Key& key):返回指向第一个大于 key 的迭代器。
  • equal_range(const Key& key):返回等于 key 的元素范围(pair<iterator, iterator>)。
示例:

6. 比较器

  • key_comp():返回用于比较键的比较器对象。
  • value_comp():返回用于比较值的比较器对象。
示例:

7. 与 STL 算法结合使用

std::map 提供了迭代器接口,可以与 STL 算法结合:

特性和注意事项

  1. 键唯一性
      • 若插入重复键,insert() 操作会失败。
      • 若需要存储重复键,使用 std::multimap
  1. 有序性
      • 默认按键升序排列,可通过自定义比较器改变排序规则。
  1. 效率
      • 插入、删除和查找操作的时间复杂度为
      • 不支持随机访问。
  1. 迭代器稳定性
      • 插入和删除操作不会使其他迭代器失效,但指向已删除元素的迭代器失效。

使用场景

  • 需要通过唯一键快速访问关联值的场景。
  • 当需要有序存储键值对并高效进行查找、插入或删除时。
  • 当键值对需要保持按顺序排列时。
 

九、std::multimap 详解

std::multimap 是 C++ 标准模板库中的有序关联容器,与 std::map 类似,但它允许一个键对应多个值。std::multimap 基于红黑树实现,提供高效的查找、插入和删除操作。

基本特点

  • 键不唯一:允许存储多个具有相同键的键值对。
  • 自动排序:键按照特定的比较规则(默认升序)自动排序。
  • 键值对存储:每个元素是一个 std::pair,其中 first 是键,second 是值。
  • 高效操作:插入、删除和查找的时间复杂度为
  • 动态大小:容器大小可以动态调整。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
  • rbegin()crbegin():返回反向迭代器,指向最后一个元素。
  • rend()crend():返回反向迭代器,指向第一个元素之前的位置。
示例:

2. 容量相关函数

  • empty():检查容器是否为空。
  • size():返回当前元素个数。
  • max_size():返回容器支持的最大元素数量。
示例:

3. 修改器函数

  • insert(const pair<Key, T>& value):插入键值对。
  • emplace(args...):直接构造键值对。
  • erase(iterator pos):删除指定位置的元素。
  • erase(const Key& key):删除所有与键匹配的元素,返回删除的元素个数。
  • erase(iterator first, iterator last):删除指定范围内的元素。
  • clear():移除所有元素。
  • swap(multimap& other):交换两个容器的内容。
示例:

4. 查找操作函数

  • find(const Key& key):查找指定键的第一个元素,返回迭代器,若未找到则返回 end()
  • count(const Key& key):返回指定键的出现次数。
  • lower_bound(const Key& key):返回指向第一个不小于 key 的迭代器。
  • upper_bound(const Key& key):返回指向第一个大于 key 的迭代器。
  • equal_range(const Key& key):返回与 key 匹配的元素范围(pair<iterator, iterator>)。
示例:

5. 比较器

  • key_comp():返回用于比较键的比较器对象。
  • value_comp():返回用于比较值的比较器对象。
示例:

6. 与 STL 算法结合使用

std::multimap 提供了迭代器接口,可以与 STL 算法结合:

特性和注意事项

  1. 键允许重复
      • std::map 的主要区别是 std::multimap 允许多个相同的键。
  1. 有序性
      • 默认按键升序排列,可通过自定义比较器改变排序规则。
  1. 效率
      • 插入、删除和查找操作的时间复杂度为
      • 不支持随机访问。
  1. 迭代器稳定性
      • 插入和删除操作不会使其他迭代器失效,但指向已删除元素的迭代器失效。

使用场景

  • 需要存储重复键并保持有序的场景。
  • 当键值对需要按顺序排列但允许多个键时。
  • 用于高效查找特定键的所有匹配值的应用。
 

十、std::unordered_set 详解

std::unordered_set 是 C++ 标准模板库中的无序容器,用于存储唯一元素,底层实现基于哈希表(hash table)。它提供了高效的插入、删除和查找操作,但元素没有特定顺序。

基本特点

  • 元素唯一性std::unordered_set 不允许重复的元素。
  • 无序存储:元素存储顺序与插入顺序或键值大小无关。
  • 底层实现:基于哈希表,通过哈希函数快速定位元素。
  • 高效操作:插入、删除和查找的平均时间复杂度为 (最坏情况下为 )。
  • 动态大小:容器大小可以动态调整。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
示例:

2. 容量相关函数

  • empty():检查容器是否为空。
  • size():返回当前元素个数。
  • max_size():返回容器支持的最大元素数量。
示例:

3. 修改器函数

  • insert(const T& value):插入元素,返回插入结果(成功或失败)。
  • emplace(args...):直接构造元素。
  • erase(iterator pos):删除指定位置的元素。
  • erase(const T& value):删除指定值的元素,返回删除的元素个数。
  • erase(iterator first, iterator last):删除指定范围内的元素。
  • clear():移除所有元素。
  • swap(unordered_set& other):交换两个容器的内容。
示例:

4. 查找操作函数

  • find(const T& value):查找指定值的元素,返回迭代器,若未找到则返回 end()
  • count(const T& value):返回指定值的出现次数(对于 std::unordered_set,结果始终为 0 或 1)。
示例:

5. 哈希相关函数

  • bucket_count():返回当前桶的数量。
  • bucket_size(size_t n):返回指定桶中元素的数量。
  • bucket(const T& value):返回元素所在的桶的编号。
  • load_factor():返回当前负载因子(元素数量 / 桶数量)。
  • max_load_factor():返回或设置允许的最大负载因子。
  • rehash(size_t n):重置桶数量,保证至少有 n 个桶。
  • reserve(size_t n):调整容器的容量以容纳 n 个元素,减少重哈希的次数。
示例:

6. 与 STL 算法结合使用

std::unordered_set 提供了迭代器接口,可以与 STL 算法结合:

特性和注意事项

  1. 唯一性
      • std::unordered_set 中元素必须唯一,插入重复元素会被忽略。
  1. 无序性
      • 元素存储顺序由哈希表决定,与插入顺序无关。
  1. 效率
      • 插入、删除和查找的平均时间复杂度为 ,但最坏情况下为 (当发生哈希冲突时)。
  1. 迭代器稳定性
      • 插入和删除操作可能导致迭代器失效。

使用场景

  • 当需要唯一元素集合但不需要有序存储时。
  • 需要快速插入、删除和查找操作的场景。
  • 使用哈希表的场景,适合需要高效管理大量数据的应用。
 

十一、std::unordered_multiset 详解

std::unordered_multiset 是 C++ 标准模板库中的无序关联容器,用于存储非唯一元素。与 std::unordered_set 类似,它底层实现基于哈希表,但允许重复的元素。

基本特点

  • 允许重复元素:与 std::unordered_set 不同,std::unordered_multiset 允许存储多个相同的值。
  • 无序存储:元素存储顺序与插入顺序或键值大小无关。
  • 底层实现:基于哈希表,通过哈希函数快速定位元素。
  • 高效操作:插入、删除和查找的平均时间复杂度为 (最坏情况下为 )。
  • 动态大小:容器大小可以动态调整。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
示例:

2. 容量相关函数

  • empty():检查容器是否为空。
  • size():返回当前元素个数。
  • max_size():返回容器支持的最大元素数量。
示例:

3. 修改器函数

  • insert(const T& value):插入元素。
  • emplace(args...):直接构造元素。
  • erase(iterator pos):删除指定位置的元素。
  • erase(const T& value):删除所有与值匹配的元素,返回删除的元素个数。
  • erase(iterator first, iterator last):删除指定范围内的元素。
  • clear():移除所有元素。
  • swap(unordered_multiset& other):交换两个容器的内容。
示例:

4. 查找操作函数

  • find(const T& value):查找指定值的元素,返回迭代器,若未找到则返回 end()
  • count(const T& value):返回指定值的出现次数。
  • equal_range(const T& value):返回与 value 匹配的元素范围(pair<iterator, iterator>)。
示例:

5. 哈希相关函数

  • bucket_count():返回当前桶的数量。
  • bucket_size(size_t n):返回指定桶中元素的数量。
  • bucket(const T& value):返回元素所在的桶的编号。
  • load_factor():返回当前负载因子(元素数量 / 桶数量)。
  • max_load_factor():返回或设置允许的最大负载因子。
  • rehash(size_t n):重置桶数量,保证至少有 n 个桶。
  • reserve(size_t n):调整容器的容量以容纳 n 个元素,减少重哈希的次数。
示例:

6. 与 STL 算法结合使用

std::unordered_multiset 提供了迭代器接口,可以与 STL 算法结合:

特性和注意事项

  1. 允许重复性
      • std::unordered_set 的主要区别是 std::unordered_multiset 允许重复的元素。
  1. 无序性
      • 元素存储顺序由哈希表决定,与插入顺序无关。
  1. 效率
      • 插入、删除和查找的平均时间复杂度为 ,但最坏情况下为 (当发生哈希冲突时)。
  1. 迭代器稳定性
      • 插入和删除操作可能导致迭代器失效。

使用场景

  • 当需要无序存储但允许重复元素的集合时。
  • 需要高效插入、删除和查找操作的场景。
  • 使用哈希表实现的场景,适合管理大量可能重复的数据。
 

十二、std::unordered_map 详解

std::unordered_map 是 C++ 标准模板库中的无序关联容器,用于存储键值对 (key-value) 数据。它底层实现基于哈希表,提供高效的查找、插入和删除操作。

基本特点

  • 键唯一性std::unordered_map 中的键是唯一的,重复键的插入操作会失败。
  • 无序存储:键值对的存储顺序与插入顺序或键值大小无关。
  • 底层实现:基于哈希表,通过哈希函数快速定位元素。
  • 高效操作:插入、删除和查找的平均时间复杂度为 (最坏情况下为 )。
  • 动态大小:容器大小可以动态调整。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
示例:

2. 容量相关函数

  • empty():检查容器是否为空。
  • size():返回当前元素个数。
  • max_size():返回容器支持的最大元素数量。
示例:

3. 元素访问函数

  • operator[]:通过键访问或插入元素。如果键不存在,会插入一个默认值。
  • at(const Key& key):通过键安全访问元素,若键不存在则抛出 std::out_of_range 异常。
示例:

4. 修改器函数

  • insert(const pair<Key, T>& value):插入键值对,返回插入结果(成功或失败)。
  • insert_or_assign(key, value):插入或更新键值对。
  • emplace(args...):直接构造键值对。
  • erase(iterator pos):删除指定位置的元素。
  • erase(const Key& key):删除指定键的元素。
  • erase(iterator first, iterator last):删除指定范围内的元素。
  • clear():移除所有元素。
  • swap(unordered_map& other):交换两个容器的内容。
示例:

5. 查找操作函数

  • find(const Key& key):查找指定键的元素,返回迭代器,若未找到则返回 end()
  • count(const Key& key):返回指定键的出现次数(对于 std::unordered_map,结果始终为 0 或 1)。
示例:

6. 哈希相关函数

  • bucket_count():返回当前桶的数量。
  • bucket_size(size_t n):返回指定桶中元素的数量。
  • bucket(const Key& key):返回键对应的桶编号。
  • load_factor():返回当前负载因子(元素数量 / 桶数量)。
  • max_load_factor():返回或设置允许的最大负载因子。
  • rehash(size_t n):重置桶数量,保证至少有 n 个桶。
  • reserve(size_t n):调整容器的容量以容纳 n 个元素,减少重哈希的次数。
示例:

7. 与 STL 算法结合使用

std::unordered_map 提供了迭代器接口,可以与 STL 算法结合:

特性和注意事项

  1. 键唯一性
      • std::unordered_map 中的键必须唯一,插入重复键会失败。
  1. 无序性
      • 元素存储顺序由哈希表决定,与插入顺序无关。
  1. 效率
      • 插入、删除和查找的平均时间复杂度为 ,但最坏情况下为 (当发生哈希冲突时)。
  1. 迭代器稳定性
      • 插入和删除操作可能导致迭代器失效。

使用场景

  • 需要通过唯一键快速访问关联值的场景。
  • 当不需要有序存储键值对时。
  • 使用哈希表的高效键值映射管理场景。
 

十三、std::unordered_multimap 详解

std::unordered_multimap 是 C++ 标准模板库中的无序关联容器,用于存储键值对 (key-value) 数据。与 std::unordered_map 不同,它允许一个键对应多个值,底层实现基于哈希表。

基本特点

  • 键允许重复:与 std::unordered_map 不同,std::unordered_multimap 允许一个键存储多个值。
  • 无序存储:键值对的存储顺序与插入顺序或键值大小无关。
  • 底层实现:基于哈希表,通过哈希函数快速定位元素。
  • 高效操作:插入、删除和查找的平均时间复杂度为 (最坏情况下为 )。
  • 动态大小:容器大小可以动态调整。

头文件

声明和初始化

成员函数详解

1. 迭代器相关函数

  • begin()cbegin():返回指向第一个元素的迭代器或常量迭代器。
  • end()cend():返回指向末尾后一个位置的迭代器或常量迭代器。
示例:

2. 容量相关函数

  • empty():检查容器是否为空。
  • size():返回当前元素个数。
  • max_size():返回容器支持的最大元素数量。
示例:

3. 修改器函数

  • insert(const pair<Key, T>& value):插入键值对。
  • emplace(args...):直接构造键值对。
  • erase(iterator pos):删除指定位置的元素。
  • erase(const Key& key):删除所有与键匹配的元素,返回删除的元素个数。
  • erase(iterator first, iterator last):删除指定范围内的元素。
  • clear():移除所有元素。
  • swap(unordered_multimap& other):交换两个容器的内容。
示例:

4. 查找操作函数

  • find(const Key& key):查找指定键的第一个元素,返回迭代器,若未找到则返回 end()
  • count(const Key& key):返回指定键的出现次数。
  • equal_range(const Key& key):返回与 key 匹配的元素范围(pair<iterator, iterator>)。
示例:

5. 哈希相关函数

  • bucket_count():返回当前桶的数量。
  • bucket_size(size_t n):返回指定桶中元素的数量。
  • bucket(const Key& key):返回键对应的桶编号。
  • load_factor():返回当前负载因子(元素数量 / 桶数量)。
  • max_load_factor():返回或设置允许的最大负载因子。
  • rehash(size_t n):重置桶数量,保证至少有 n 个桶。
  • reserve(size_t n):调整容器的容量以容纳 n 个元素,减少重哈希的次数。
示例:

6. 与 STL 算法结合使用

std::unordered_multimap 提供了迭代器接口,可以与 STL 算法结合:

特性和注意事项

  1. 键允许重复
      • std::unordered_map 的主要区别是 std::unordered_multimap 允许重复的键。
  1. 无序性
      • 键值对存储顺序由哈希表决定,与插入顺序无关。
  1. 效率
      • 插入、删除和查找的平均时间复杂度为 ,但最坏情况下为 (当发生哈希冲突时)。
  1. 迭代器稳定性
      • 插入和删除操作可能导致迭代器失效。

使用场景

  • 需要无序存储并允许重复键的关联数据场景。
  • 需要快速插入、删除和查找操作的场景。
  • 适用于管理大量数据,且对键值对存储顺序无要求的场景。
 

十四、std::stack 详解

std::stack 是 C++ 标准模板库中的适配器容器,用于实现“后进先出”(LIFO,Last In First Out)的栈数据结构。std::stack 并不是一个独立的容器,而是通过封装其他序列容器(默认是 std::deque)实现的。

基本特点

  • 后进先出:栈的操作遵循 LIFO 原则。
  • 容器适配器std::stack 基于底层容器实现,支持 std::deque(默认)、std::vectorstd::list
  • 高效操作:提供常数时间复杂度的插入和删除操作。
  • 动态大小:底层容器可以动态调整大小。

头文件

声明与初始化

成员函数详解

1. 容量相关函数

  • empty():检查栈是否为空。
  • size():返回栈中元素的个数。
示例:

2. 元素访问函数

  • top():返回栈顶元素的引用。
示例:

3. 修改器函数

  • push(const T& value):将元素压入栈顶。
  • emplace(args...):在栈顶直接构造元素。
  • pop():移除栈顶元素。
  • swap(stack& other):交换两个栈的内容。
示例:

4. 不能与 STL 算法直接结合

由于 std::stack 不提供迭代器接口,因此不能直接与 STL 算法结合。如果需要算法支持,应直接操作底层容器。

特性和注意事项

  1. 底层容器
      • 默认使用 std::deque 作为底层容器。
      • 可以指定其他支持 push_backpop_backback 的容器,如 std::vectorstd::list
  1. 只能访问栈顶元素
      • std::stack 不提供对底层容器的直接访问。
      • 若需要遍历或随机访问,应使用底层容器。

使用场景

  • 当需要模拟 LIFO 数据结构时。
  • 用于递归的替代方案,例如深度优先搜索(DFS)。
  • 实现回溯算法(如括号匹配、路径回溯等)。
 

十五、std::queue 详解

std::queue 是 C++ 标准模板库中的适配器容器,用于实现“先进先出”(FIFO,First In First Out)的队列数据结构。它通过封装其他序列容器(默认是 std::deque)实现。

基本特点

  • 先进先出:队列的操作遵循 FIFO 原则。
  • 容器适配器std::queue 基于底层容器实现,支持 std::deque(默认)或 std::list
  • 高效操作:提供常数时间复杂度的插入和删除操作。
  • 动态大小:底层容器可以动态调整大小。

头文件

声明与初始化

成员函数详解

1. 容量相关函数

  • empty():检查队列是否为空。
  • size():返回队列中元素的个数。
示例:

2. 元素访问函数

  • front():返回队列中第一个元素的引用。
  • back():返回队列中最后一个元素的引用。
示例:

3. 修改器函数

  • push(const T& value):将元素添加到队列尾部。
  • emplace(args...):在队列尾部直接构造元素。
  • pop():移除队列首元素。
  • swap(queue& other):交换两个队列的内容。
示例:

4. 与 STL 算法结合

由于 std::queue 不提供迭代器接口,因此不能直接与 STL 算法结合。如果需要算法支持,应直接操作底层容器。

特性和注意事项

  1. 底层容器
      • 默认使用 std::deque 作为底层容器。
      • 可以指定其他支持 push_backpop_frontfrontback 的容器,如 std::list
  1. 只能访问队首和队尾元素
      • std::queue 不提供对底层容器的直接访问。
      • 若需要遍历或随机访问,应使用底层容器。

使用场景

  • 模拟 FIFO 数据结构的场景,例如任务调度、消息队列。
  • 用于广度优先搜索(BFS)等算法。
  • 用于生产者-消费者模型。
 

十六、std::priority_queue 详解

std::priority_queue 是 C++ 标准模板库中的容器适配器,用于实现优先队列。优先队列是一种特殊的队列,其中元素按照优先级顺序排列,优先级最高的元素总是位于队首。

基本特点

  • 优先级队列:元素以优先级顺序存储,默认是最大堆(即优先级最高的元素位于队首)。
  • 容器适配器std::priority_queue 基于底层容器实现,通常使用 std::vector(默认)或 std::deque
  • 动态大小:底层容器可以动态调整大小。
  • 底层实现:基于堆结构(默认最大堆),元素按照堆排序规则排列。

头文件

声明与初始化

成员函数详解

1. 容量相关函数

  • empty():检查优先队列是否为空。
  • size():返回优先队列中元素的个数。
示例:

2. 元素访问函数

  • top():返回优先队列中优先级最高的元素。
示例:

3. 修改器函数

  • push(const T& value):将元素添加到优先队列。
  • emplace(args...):在优先队列中直接构造元素。
  • pop():移除优先队列中优先级最高的元素。
示例:

4. 与 STL 算法结合

std::priority_queue 不直接支持迭代器,因此无法与 STL 算法直接结合。但可以通过底层容器操作堆。
示例:使用 std::make_heap 操作底层容器:

自定义优先级

1. 最小堆

默认情况下,std::priority_queue 是最大堆。如果需要最小堆,可以使用 std::greater<T> 作为比较器。
示例:

2. 自定义比较器

可以通过自定义函数对象或函数指针定义优先级规则。
示例:

特性和注意事项

  1. 默认最大堆
      • 默认情况下,std::priority_queue 是最大堆,即优先级最高的元素位于队首。
  1. 底层容器
      • 默认使用 std::vector 作为底层容器。
      • 可以指定其他支持随机访问的容器(如 std::deque)。
  1. 只能访问队首元素
      • 无法遍历或随机访问其他元素,若需要完整数据操作,应操作底层容器。

使用场景

  • 任务调度:优先处理高优先级任务。
  • 数据流处理:快速找出最大或最小元素。
  • 实现复杂算法:如 Dijkstra 最短路径、Prim 最小生成树。
 

十七、总结

以下是关于 顺序容器关联容器无序关联容器容器适配器 的全面对比表格:
类别
容器
头文件
特性
顺序容器
array
<array>
固定大小的静态数组,提供 STL 接口,编译时确定大小。
vector
<vector>
动态数组,支持快速随机访问,尾部插入和删除效率高。
deque
<deque>
双端队列,支持两端高效插入和删除,随机访问稍慢于 vector
forward_list
<forward_list>
单向链表,轻量级,适合头部插入和删除,不支持随机访问。
list
<list>
双向链表,支持快速任意位置插入和删除,遍历性能较低,不支持随机访问。
关联容器
set
<set>
有序集合,元素唯一,自动按升序排列,基于红黑树实现。
multiset
<set>
有序多重集合,允许重复元素,自动按升序排列,基于红黑树实现。
map
<map>
有序键值对集合,键唯一,自动按升序排列,基于红黑树实现。
multimap
<map>
有序键值对集合,允许重复键,自动按升序排列,基于红黑树实现。
无序关联容器
unordered_set
<unordered_set>
无序集合,元素唯一,基于哈希表实现,查找、插入和删除效率高。
unordered_multiset
<unordered_set>
无序多重集合,允许重复元素,基于哈希表实现,查找、插入和删除效率高。
unordered_map
<unordered_map>
无序键值对集合,键唯一,基于哈希表实现,查找、插入和删除效率高。
unordered_multimap
<unordered_map>
无序键值对集合,允许重复键,基于哈希表实现,查找、插入和删除效率高。
容器适配器
stack
<stack>
后进先出(LIFO)栈,基于 deque 或其他序列容器实现。
queue
<queue>
先进先出(FIFO)队列,基于 deque 或其他序列容器实现。
priority_queue
<queue>
优先级队列,默认最大堆,基于 vector 容器实现。

对比说明

  1. 顺序容器
      • 提供连续或链式存储,适合顺序数据操作。
      • 以动态数组(如 vector)和链表(如 list)为代表,支持插入、删除和遍历操作。
  1. 关联容器
      • 提供键值对或唯一元素集合,元素有序存储。
      • mapset 为代表,基于红黑树实现,查找效率为
  1. 无序关联容器
      • 提供无序存储,适合需要高效查找和插入的场景。
      • 以哈希表为底层实现,查找效率平均为 ,最坏为
  1. 容器适配器
      • 封装底层容器,提供特定的数据结构功能。
      • stackqueue 为代表,限制了操作接口以实现特定行为。

函数支持对比表

功能分类
支持的函数
顺序容器
关联容器
无序关联容器
容器适配器
构造与销毁
构造函数
arrayvectordequelist
setmapmultisetmultimap
unordered_setunordered_mapunordered_multiset,unordered_multimap
stackqueuepriority_queue
析构函数
operator=
assign
迭代器支持
begin() / end()
✅ 支持
✅ 支持
✅ 支持
❌ 不支持
cbegin() / cend()
✅ 支持
✅ 支持
✅ 支持
❌ 不支持
rbegin() / rend()
✅ 支持
✅ 支持
❌ 不支持
❌ 不支持
crbegin() / crend()
✅ 支持
✅ 支持
❌ 不支持
❌ 不支持
容量管理
size() / max_size()
✅ 支持
✅ 支持
✅ 支持
✅ 支持
empty()
✅ 支持
✅ 支持
✅ 支持
✅ 支持
capacity()
✅ (vector, deque)
reserve()
✅ (vector)
✅ 支持
resize()
✅ 支持
元素访问
at()
✅ (vector, deque)
operator[]
✅ (vector, deque)
✅ (map)
✅ (unordered_map)
front() / back()
✅ 支持
✅(stackqueue 的变体)
修改器
insert()
✅ 支持
✅ 支持
✅ 支持
emplace()
✅ 支持
✅ 支持
✅ 支持
✅(部分支持)
erase()
✅ 支持
✅ 支持
✅ 支持
push_back() / pop_back()
✅ (vector, deque)
push_front() / pop_front()
✅ (deque, list)
✅(queue 支持)
clear()
✅ 支持
✅ 支持
✅ 支持
swap()
✅ 支持
✅ 支持
✅ 支持
排序操作
sort()
✅ (list)
merge()
✅ (list)
✅ 支持
unique()
✅ (list)
reverse()
✅ (list)
链表特性
splice() / splice_after()
✅ (list, forward_list)
查找操作
find()
✅ 支持
✅ 支持
count()
✅ (list)
✅ 支持
✅ 支持
lower_bound() / upper_bound()
✅ 支持
equal_range()
✅ 支持
✅ 支持
contains()
✅(C++20 起)
✅(C++20 起)
观察器
key_comp() / value_comp()
✅ 支持
哈希操作
bucket_count() / bucket()
✅ 支持
load_factor() / max_load_factor()
✅ 支持
适配器特性
top() / front() / back()
✅(stackqueue 支持)
push() / pop()
✅ 支持
分配器
get_allocator()
✅ 支持
✅ 支持
✅ 支持

进一步说明

  1. 顺序容器 提供丰富的修改器和迭代器功能,适合动态大小和顺序存储的需求,操作简单但遍历复杂度取决于实现。
  1. 关联容器 适合存储有序键值对,支持高效查找,但随机访问性能较差。
  1. 无序关联容器 是关联容器的哈希版本,适合需要快速插入和查找的场景,但对顺序没有要求。
  1. 容器适配器 提供特定功能(如栈、队列),其功能受到严格限制以适应目标用途。
 

十八、std::bitset详解

std::bitset 是 C++ 标准库中的一个容器类,用于管理和操作固定大小的位集合。它提供了一种高效的方式来存储和操作位数据。

头文件


特点

  • 固定大小:位集合大小在编译时确定,不能动态调整。
  • 高效存储:每个位占用 1 位内存,适合处理布尔数据。
  • 功能丰富:支持按位操作、位翻转、位访问等操作。
  • 适合位操作应用:如位掩码、布尔向量、状态集合等。

构造与初始化

常用成员函数

函数
描述
示例
size()
返回位集合的大小。
b1.size();
count()
返回位集合中值为 1 的位数。
b1.count();
any()
检查是否至少有一个位为 1。
b1.any();
none()
检查是否所有位都为 0。
b1.none();
all()
检查是否所有位都为 1。
b1.all();
set()
将所有位设置为 1,或设置指定位置为 1。
b1.set(); b1.set(2);
reset()
将所有位设置为 0,或设置指定位置为 0。
b1.reset(); b1.reset(2);
flip()
翻转所有位或指定位置的位。
b1.flip(); b1.flip(2);
test()
检查指定位置的位是否为 1。
b1.test(2);
operator[]
返回指定位置位的值(只读访问)。
b1[2];
to_string()
返回 bitset 的字符串表示。
b1.to_string();
to_ulong()
将 bitset 转换为无符号长整数(位数不超过 unsigned long 大小)。
b1.to_ulong();

按位操作支持

std::bitset 支持按位操作符(&, |, ^, ~)和移位操作符(<<, >>)。
示例:

示例代码


十九、std::pair详解

std::pair 是 C++ 标准库中的一个简单容器,用于存储两个值(称为 firstsecond)。这两个值可以是不同类型。

头文件


特点

  • 用于将两个关联值打包成一个单元。
  • 常用于返回多个值的函数。
  • 提供成员函数和运算符重载。

构造与初始化

常用成员

成员变量
描述
示例
first
存储第一个值。
p1.first = 10;
second
存储第二个值。
p1.second = "example";

常用函数

函数
描述
示例
make_pair
创建一个 pair,推导元素类型。
auto p = std::make_pair(1, "text");
operator==
检查两个 pair 是否相等。
if (p1 == p2) {...}
operator<
按字典序比较两个 pair,先比较 first,若相等则比较 second
if (p1 < p2) {...}

示例代码


二十、STL中常用算法

STL 中常用算法库详解

C++ 标准模板库(STL)中提供了丰富的算法库,用于操作容器中的元素。算法库主要定义在头文件 <algorithm><numeric> 中,包括排序、查找、修改、数值计算等多种算法。
以下是 STL 算法库中常用算法的分类及其详细说明:

1. 排序算法

算法
描述
复杂度
示例
sort
对范围内元素进行升序排序,支持自定义比较函数。
std::sort(v.begin(), v.end());
stable_sort
稳定排序,保证相等元素的相对顺序。
std::stable_sort(v.begin(), v.end());
partial_sort
对范围内前 k 个元素排序,其他元素顺序不定。
std::partial_sort(v.begin(), v.begin() + k, v.end());
nth_element
将第 n 小的元素放到正确位置,左侧小于 n,右侧大于 n。
std::nth_element(v.begin(), v.begin() + n, v.end());
is_sorted
检查范围内的元素是否已经按升序排列。
bool sorted = std::is_sorted(v.begin(), v.end());

2. 查找算法

算法
描述
复杂度
示例
find
查找范围内第一个等于指定值的元素,返回迭代器。
auto it = std::find(v.begin(), v.end(), value);
find_if
查找满足条件的第一个元素,返回迭代器。
auto it = std::find_if(v.begin(), v.end(), predicate);
find_if_not
查找第一个不满足条件的元素,返回迭代器。
auto it = std::find_if_not(v.begin(), v.end(), predicate);
binary_search
在有序范围内进行二分查找,返回是否找到指定值。
bool found = std::binary_search(v.begin(), v.end(), value);
lower_bound
返回第一个大于等于值的元素迭代器(在有序范围内)。
auto it = std::lower_bound(v.begin(), v.end(), value);
upper_bound
返回第一个大于值的元素迭代器(在有序范围内)。
auto it = std::upper_bound(v.begin(), v.end(), value);
equal_range
返回等于值的范围(两个迭代器)。
auto range = std::equal_range(v.begin(), v.end(), value);

3. 修改算法

算法
描述
复杂度
示例
copy
将范围内的元素复制到另一个范围。
std::copy(v.begin(), v.end(), dest.begin());
copy_if
将满足条件的元素复制到另一个范围。
std::copy_if(v.begin(), v.end(), dest.begin(), predicate);
move
将范围内的元素移动到另一个范围。
std::move(v.begin(), v.end(), dest.begin());
transform
将范围内的元素通过函数变换后复制到另一个范围。
std::transform(v.begin(), v.end(), dest.begin(), func);
replace
将范围内等于某值的元素替换为另一个值。
std::replace(v.begin(), v.end(), old_value, new_value);
replace_if
替换满足条件的元素为指定值。
std::replace_if(v.begin(), v.end(), predicate, new_value);
remove
移动等于指定值的元素到范围末尾,不改变容器大小。
auto it = std::remove(v.begin(), v.end(), value);
remove_if
移动满足条件的元素到范围末尾,不改变容器大小。
auto it = std::remove_if(v.begin(), v.end(), predicate);
unique
移动相邻的重复元素到范围末尾,不改变容器大小。
auto it = std::unique(v.begin(), v.end());
reverse
反转范围内的元素顺序。
std::reverse(v.begin(), v.end());
rotate
将范围内的元素旋转。
std::rotate(v.begin(), v.middle(), v.end());

4. 数值计算算法

算法
描述
复杂度
示例
accumulate
计算范围内元素的累加和,可使用自定义操作。
int sum = std::accumulate(v.begin(), v.end(), 0);
inner_product
计算两个范围内元素的内积。
int dot = std::inner_product(a.begin(), a.end(), b.begin(), 0);
adjacent_difference
计算相邻元素的差值并存储到另一范围。
std::adjacent_difference(v.begin(), v.end(), result.begin());
partial_sum
计算范围内的部分和(前缀和)。
std::partial_sum(v.begin(), v.end(), result.begin());
iota
填充范围内的元素为连续递增值。
std::iota(v.begin(), v.end(), 0);

5. 集合操作算法

算法
描述
复杂度
示例
set_union
计算两个范围的并集,结果存储到另一个范围。
std::set_union(a.begin(), a.end(), b.begin(), b.end(), result.begin());
set_intersection
计算两个范围的交集,结果存储到另一个范围。
std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), result.begin());
set_difference
计算两个范围的差集,结果存储到另一个范围。
std::set_difference(a.begin(), a.end(), b.begin(), b.end(), result.begin());
set_symmetric_difference
计算两个范围的对称差集,结果存储到另一个范围。
std::set_symmetric_difference(a.begin(), a.end(), b.begin(), b.end(), result.begin());

6. 其他通用算法

算法
描述
复杂度
示例
for_each
对范围内的每个元素应用指定的操作。
std::for_each(v.begin(), v.end(), [](int x){ std::cout << x; });
min_element
返回范围内最小元素的迭代器。
auto it = std::min_element(v.begin(), v.end());
max_element
返回范围内最大元素的迭代器。
auto it = std::max_element(v.begin(), v.end());
minmax_element
同时返回范围内最小和最大元素的迭代器(std::pair)。
auto result = std::minmax_element(v.begin(), v.end());
all_of
检查范围内是否所有元素都满足条件。
bool result = std::all_of(v.begin(), v.end(), [](int x){ return x > 0; });
any_of
检查范围内是否至少有一个元素满足条件。
bool result = std::any_of(v.begin(), v.end(), [](int x){ return x > 0; });
none_of
检查范围内是否所有元素都不满足条件。
bool result = std::none_of(v.begin(), v.end(), [](int x){ return x > 0; });
equal
检查两个范围内的元素是否相等(按顺序比较)。
bool result = std::equal(v1.begin(), v1.end(), v2.begin());
mismatch
返回两个范围内首个不匹配的元素对的迭代器。
auto result = std::mismatch(v1.begin(), v1.end(), v2.begin());
lexicographical_compare
按字典序比较两个范围,返回是否第一个范围小于第二个范围。
bool result = std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end());
swap_ranges
交换两个范围的元素内容。
std::swap_ranges(v1.begin(), v1.end(), v2.begin());
shuffle
将范围内的元素按随机顺序重新排列(需要随机数生成器)。
std::shuffle(v.begin(), v.end(), std::default_random_engine());

上一篇
C++面向对象编程
下一篇
Leetcode刷题——10月

评论
Loading...
目录