C++ STL容器
C++中STL常用容器主要分为三大类:顺序容器,关联式容器和容器适配器
一、顺序式容器
顺序性容器就是将一组具有相同类型的元素以严格的线性形式组织起来
容器 | 简介说明 |
---|---|
vector | 可变大小数组。相当于数组,可动态构建,支持随机访问,无头插和尾插,仅支持inset插入,除尾部外的元素删除比较麻烦。但使用最为广泛 |
deque | 双端队列。支持头插、删,尾插、删,随机访问较vector容器来说慢,但对于首尾的数据操作比较方便 |
list | 双向循环链表。使用起来很高效,对于任意位置的插入和删除都很快,在操作过后,以后指针、迭代器、引用都不会失效 |
forward_list | 单向链表。只支持单向访问,在链表的任何位置进行插入/删除操作都非常快 |
array | 固定数组。vector的底层即为array数组,它保存了一个以严格顺序排列的特定数量的元素 |
顺序式容器使用场景
多数的场景都可以使用vector容器。
如果需要在一串数字的头尾进行操作,偏向deque,对于较中间的元素操作,不推荐 ;
对于中间的元素插入或删除,可采用forward_list(单向链表)或list(双向链表),不需要移动元素,只需改变相关结点的指针域即可;
Vector
vector为可变长数组(动态数组),定义的vector数组可以随时添加数值和删除元素.
在局部函数中开vector数组,是在堆空间里面开的,所以经常见到在局部函数中开大容量数组
-
初始化
一维初始化
vector<int>num; //定义了一个名为num的存int数据的一维数组
vector<double>num;//定义了一个名为num的存double数据的一维数组
vector<node>num;//node是结构体类型
指定长度和初始值的初始化
vector<int> v(n);//定义一个长度为n的数组,动态定义,不指定初值默认初值为0
vector<int> v(n, 0);//所有的元素均为0
初始化中有多个元素
vector<int> a{1, 2, 3, 4, 5};// 数组a中有五个元素
拷贝初始化
vector<int> a(n + 1, 0);
vector<int> b(a);//两个数组中的类型必须相同,a和b都是长度为n+1,所有值都为0的数组
二维初始化vector<vectot<int> >num;//定义一个行和列均可变的二维数组
行列长度均固定 n + 1行 m + 1列初始值为0
vector<vector<int> > a(n + 1, vector<int>(m + 1, 0));
// c++17或者c++20支持的形式
vector a(n + 1, vector(m + 1, 0));
赋值操作
赋值的话可以使用assign()函数,也可以使用其他方式
//直接赋值
vector<int> v2;
v2 = v1;
//assign赋值
vector<int> v3;
v3.assign(v1.begin(), v1.end());
//n个element赋值
vector<int> v4;
v4.assign(10, 100);
-
相关函数
代码 含义
c.front() 返回第一个数据
c.pop_back() 删除最后一个数据 O(1)
c.push_back(element) 在尾部加一个数据 O(1)
c.size() 返回实际数据个数(unsigned类型) O(1)
c.clear() 清除元素个数 O(N),N为元素个数
c.resize(n,v) 改变数组大小为n,n个空间数值赋为v,如果没有默认赋值为0
c.insert(it,x) 向任意迭代器it插入一个元素x O(N)
例:c.insert(c.begin()+2,-1) 将-1插入c[2]的位置
c.erase(first,last) 删除[first,last)的所有元素
c.begin() 返回首元素的迭代器(通俗来说就是地址)
c.end() 返回最后一个元素后一个位置的迭代器(地址)
c.empty() 判断是否为空,为空返回真,反之返回假
end()返回的是最后一个元素的后一个位置的地址,不是最后一个元素的地址,所有容器均是如此
二、关联式容器
关联式容器每一个元素都有一个键值(key),对于二元关联容器,还拥有实值(value)容器中的元素顺序不能由程序员来决定,有set(集合)和map(映射)这两大类,它们均是以RB-Tree(red-black tree,红黑树)为底层架构。
容器 | 简介说明 |
---|---|
set/mutliset | 集合/多重集合。对于set,在使用insert插入元素时,已插入过的元素不可重复插入,这正好符合了集合的互异性,在插入完成显示后,会默认按照升序进行排序,对于multiset,可插入多个重复的元素 |
map/mutlimap | 映射/多重映射。二者均为二元关联容器(在构造时需要写两个参数类型,前者对key值,后者对应value值),因为有两个参数,因此在插入元素的时候需要配合对组pair进行插入 |
关联式容器的使用场景
如果只负责查找内容,具体到某个单位,使用场景比如对手机游戏的个人的计分的存储,可以使用set或mutliset
如果需要同时放入容器的数据不止一个,并且是不同类型,比如一个为整型int,一个为string字符串型,就可以考虑使用map或mutlimap
三、容器适配器
容器适配器是一个封装了序列容器的一个类模板,它在一般的序列容器的基础上提供了一些不同的功能。之所以称为容器适配器,是因为它是适配容器来提供其它不一样的功能。通过对应的容器和成员函数来实现我们需要的功能
容器 | 简介说明 |
---|---|
stack | 堆栈。其原理是先进后出(FILO),其底层容器可以是任何标准的容器适配器,默认为deque双端队列 |
queue | 队列。其原理是先进先出(FIFO),只有队头和队尾可以被访问,故不可有遍历行为,默认也为deque双端队列 |
pirority_queue | 优先队列。它的第一个元素总是它所包含的元素中优先级最高的,就像数据结构里的堆,会默认形成大堆,还可以使用仿函数来控制生成大根堆还是生成小根堆,若没定义,默认使用vector容器 |
参考资料:
https://zhuanlan.zhihu.com/p/564057584
https://blog.csdn.net/qq_50285142/article/details/122303529
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具