STL容器 — 总结

1. 什么是容器

  C++容器是标准模板库STL的核心组件,本质上是预定义的、类型安全的"数据盒子"。它们以模板类的形式提供了一套即插即用的数据结构(如动态数组、链表、树等),通过自动管理内存和提供通用操作接口(增删查改),简化了数据集合的存储与处理流程。

2. 容器分类

C++容器分类及常用容器如下:

2.1. 顺序容器

  顺序容器中的顺序两个字儿指的是元素插入序列的顺序,和元素的值没有关系。

  • vector:动态数组,变长数组,容量不够时会自动扩容,在尾部增加或删除元素的效率最高(O(1) 常数阶),在其它位置插入或删除元素效率较差(O(n) 线性阶)。
  • deque:双端队列,和 vector 非常相似,区别在于使用该容器不仅尾部插入和删除元素高效,在头部插入或删除元素也同样高效,时间复杂度都是 O(1) 常数阶,但是在容器中某一位置处插入或删除元素,时间复杂度为 O(n) 线性阶。
  • list:双向链表,可以在序列的任意位置高效地增加或删除元素(O(1)),但访问容器中任意元素的速度要比前三种容器慢,这是因为链表这种东西必须从第一个元素或最后一个元素开始访问,需要沿着链表移动,直到到达想要的元素。
  • forward_list:单向链表,以单链表的形式组织元素,内部的元素只能从第一个元素开始访问,比链表容器快、更节省内存。
  • array:基于数组,大小固定。

2.2. 关联容器

  分为有序和无序两种,分配基于红黑树和哈希表实现。

2.2.1. 有序关联容器

  底层为红黑树,,排序容器中的元素是按序插入的(默认按的升序排列),所以有序关联容器在查找时具有非常好的性能。

  • set:唯一键集合
  • map:键值对映射
  • multiset:允许重复键的集合
  • multimap:允许重复键的映射

2.2.2. 无序关联容器

  底层为哈希表,和有序关联容器不同,哈希容器中的元素是未排序的,元素的位置由哈希函数确定。

  • unordered_set:哈希集合
  • unordered_map:哈希映射
  • unordered_multiset:允许重复键的哈希集合
  • unordered_multimap:允许重复键的哈希映射

2.3. 容器适配器

  封装基础容器来提供特定的功能。

  • stack:后进先出(LIFO)栈
  • queue:先进先出(FIFO)队列
  • priority_queue:优先级队列(默认最大堆)

2.4. 其他特殊容器

  • string(常作为独立容器使用)

3. 容器的访问与遍历

3.1. 容器迭代器

  使用迭代器访问或便利 容器中的元素,指定容器中的一段区间,用于遍历容器中的元素。STL 标准库为每一种标准容器定义了一种迭代器类型,这意味着,不同容器的迭代器也不同,其功能强弱也有所不同。

3.2. 常用迭代器

下面展示容器的常见成员函数,这些成员函数返回一个特定的迭代器。

1
2
begin()
end()
1
2
rbegin()
rend()     # 指向第一个元素的前一个位置, 因为容器是头闭尾开的区间, 也就是`[begin, end)`。
1
cbegin()
1
2
crbegin()
crend()

3.3. 迭代器分类

  可以理解为对于指针的封装,常用的迭代器可以分为分为输入迭代器输出迭代器前向迭代器双向迭代器随机访问迭代器 5 种。其中输入迭代器和输出迭代器比较特殊,它们不是把数组或容器当做操作对象,而是把输入流/输出流作为操作对象。

  1. 前向迭代器(forward iterator)
    支持的操作: ++*(可以被复制或赋值)、使用 == 和 != 运算符进行比较。此外,两个前向迭代器可以互相赋值。

  2. 双向迭代器(bidirectional iterator)
    支持的操作: 前向迭代器的全部功能,以及--

  3. 随机访问迭代器(random access iterator)
    随机访问迭代器具有双向迭代器的全部功能。除此之外,还支持随机访问操作p[i]+或者-一个整数、两个随机访问迭代器相减。

3.4. 不同容器支持的迭代器类型

容器 迭代器类型
array 随机访问迭代器
vector 随机访问迭代器
deque 随机访问迭代器
list 双向迭代器
set / multiset 双向迭代器
map / multimap 双向迭代器
forward_list 前向迭代器
unordered_map / unordered_multimap 前向迭代器
unordered_set / unordered_multiset 前向迭代器
stack 不支持迭代器
queue 不支持迭代器

  不是所有的容器都支持迭代器,支持迭代器的容器称为range。容器适配器 stack 和 queue 就没有迭代器,但是它们包含有一些成员函数,可以用来对元素进行访问。

comments powered by Disqus