STL容器是C++标准库中用于存储和管理数据结构的模板类。STL容器具有很强的灵活性和泛型设计,允许开发者将不同类型的数据存储在不同的容器中,并配合算法一起使用,STL容器分为三大类:顺序容器、关联容器和无序容器
一、顺序容器
顺序容器按照线性顺序存储和访问元素,通常适用于需要频繁插入、删除、遍历和访问得场景
1、vector
动态数组,存储在连续的内存块中,支持随机访问,并且在末尾插入和删除元素十分高效。但在中间插入和删除元素时性能较差
特点 : 支持随机访问,动态扩展大小,超出容量时会重新分配内存,插入/删除在末尾为O(1),中间操作为O(n)
std::vector<int> vec = {1, 2, 3};
vec.push_back(4); // 向末尾添加元素
vec.pop_back(); // 删除末尾元素
int val = vec[0]; // 访问第一个元素
2、deque
双端动态数组,允许在两段高效的插入和删除元素,与vector不同,deque在两端的插入和删除都i具有O(1)的复杂度
特点 : 支持随机访问,在头部和尾部插入和删除的效率高,可以动态扩展
std::deque<int> dq = {1, 2, 3};
dq.push_back(4); // 向末尾添加元素
dq.push_front(0); // 向头部添加元素
dq.pop_back(); // 删除末尾元素
dq.pop_front(); // 删除头部元素
3、list
双向链表,适合需要频繁插入和删除元素的场景,但不支持随机访问
特点 : 不支持随机访问,访问元素的方式需要从头部遍历到尾部,插入和删除任意效率都为O(1)
std::list<int> lst = {1, 2, 3};
lst.push_back(4); // 向末尾添加元素
lst.push_front(0); // 向头部添加元素
lst.pop_back(); // 删除末尾元素
lst.pop_front(); // 删除头部元素
4、forward_list
单向链表,只能沿一个方向遍历,相比较list,它占用的内存较少
特点 : 只能从头到尾遍历,不能逆向遍历,头部的插入和删除都为O(1)
std::forward_list<int> flst = {1, 2, 3};
flst.push_front(0); // 向头部添加元素
flst.pop_front(); // 删除头部元素
5、array
固定大小的数据,大小在编译时确定,性能与C数组类似,但提供了STL容器接口
特点 :大小固定,不能动态扩展,支持随机访问,时间复杂度为O(1)
std::array<int, 3> arr = {1, 2, 3};
int val = arr[0]; // 访问第一个元素
二、关联容器
关联容器通过键值对存储数据,通常基于红黑树等平衡二叉树实现,所有元素会自动按键值对排序
1、set
存储唯一元素,按键值排序,查找和删除的时间复杂度为O(log n)
特点 : 不允许重复元素,所有元素按键值自动排序
std::set<int> s = {3, 1, 2};
s.insert(4); // 插入元素
s.erase(2); // 删除元素
2、map
存储键值对的关联容器,键是唯一的,按键值排序
特点 : 键唯一,自动排序,访问和插入时间复杂度为O(log n)
std::map<int, std::string> m;
m[1] = "one"; // 插入键值对
m[2] = "two"; // 插入键值对
3、multiset
允许存储重复元素,其他行为与set相似
std::multiset<int> ms = {1, 2, 2, 3};
ms.insert(2); // 插入重复元素
4、multimap
允许存储重复键的键值对,其他行为与map相似
std::multimap<int, std::string> mm;
mm.insert({1, "one"});
mm.insert({1, "uno"}); // 允许重复键
三、无序容器
无序容器基于哈希表实现,元素的排列顺序不固定,查找、插入和删除的平均时间复杂度为O(1)
1、unordered_set
不重复集合,元素按照哈希值存储,查找效率高
std::unordered_set<int> us = {1, 2, 3};
us.insert(4); // 插入元素
2、unordered_map
基于哈希表键值对容器,键是唯一的,适合高效查找的场景
std::unordered_map<int, std::string> um;
um[1] = "one";
3、unordered_multiset
允许重复元素的无序集合,其他特性与unoedered_set类似
std::unordered_multiset<int> ums = {1, 2, 2, 3};
4、unordered_multimap
允许重复键的无序键值对容器,其他特性与unordered_map类似
std::unordered_multimap<int, std::string> umm;
umm.insert({1, "one"});
四、容器适配器
容器适配器是对现有容器进行封装,提供特定的接口以实现特定的数据结构
1、stack
基于LIFO(后进先出)原则的容器适配器,通常由deque或vextor实现
std::stack<int> stk;
stk.push(1); // 入栈
stk.pop(); // 出栈
2、queue
基于FIFO(先进先出)原则的容器适配器,通常由deque实现
std::queue<int> q;
q.push(1); // 入队
q.pop(); // 出队
3、priority_queue
基于堆的优先队列,元素按优先级排序(默认是最大堆)
std::priority_queue<int> pq;
pq.push(10);
pq.push(5);
pq.push(20); // 20 位于队首