#创作计划# c++容器:从入门到入土
2025-08-13 17:49:48
发布于:河北
第一部分:为什么要学习c++容器
- 容器是c++中管理数据的高效工具
- 容器也是c++中存放数据的盒子
- c++标准库(STL)就提供了多种容器
本篇文章将会讲解STL中最常用的6中容器
- vector 动态数组
- list 双向链表
- map 有序键值对
- set 有序集合
- queue 队列
- stack 栈
第二部分:容器基础——先搞懂这两个概念
什么是STL?
- STL(Standard Template Library)标准模版库 是c++自带的工具集
- 包含容器、算法、迭代器,三者缺一不可
什么是迭代器
- 迭代器(Iterator)是访问容器的关键部分
- 由于不同容器底层结构不同,所以就需要一种统一的方式遍历容器,这就是迭代器
第三部分:比赛、写题常用的6个容器详细介绍
如果你不用万能头,一定要在每个代码前面的头文件都加上#include<容器名>
第3.1部分:vector
vector 是什么和它的底层原理
- vector是动态数组(动态分配的数组)
- 底层原理:预先分配一块内存,当存满时自动扩容
vector 的优缺点
- 优点:随机访问快
- 缺点:中间插入元素慢
vector 的核心用法
#include <bits/stdc++.h>
using namespace std;
int main(){
// 1. 定义和初始化
vector<int> v1;// 空vector
vector<int> v2(3,0);// vector中有3个元素0
vector<int> v3 = {1,2,3};// vector中有3个元素。分别是1 2 3-->初始化列表
// 2.1. 向尾部添加元素
v1.push_back(1);// v1 = {1}
v2.push_back(1);// v2 = {0,0,0,1}
v3.push_back(1);// v3 = {1,2,3,1}
// 2.2 从某一位置删除元素
v2.erase(v2.begin() + 2); // 删除第三个元素(下标为2),v2 = {0,0,1}
// 3.访问某个元素
// 越界时不报错
cout << v1[1] << endl;// 越界,输出为0
cout << v1[0] << endl;// 不越界,输出为1(因为下标为0的那一项就是1)
// 越界时抛异常
cout << v1.at(1) << endl; 越界,抛出异常
cout << v1.at(0) << endl;// 不越界,输出为1(因为下标为0的那一项就是1)
// 4.遍历(迭代器、范围for)
// 要是想知道这项的下标是多少,需要手动维护
// 迭代器方案
int idx1 = 0;
for (vector<int>::iterator it = v2.begin(); it != v2.end(); ++it) {
cout << *it << " " << idx1++ << endl; // 解引用迭代器获取元素
}
// 范围for方案
int idx2 = 0;
for (int num : v3){
cout << num << " " << idx2++ << endl;
}
// 5. 其他函数
// 求vector数组长度
cout << v3.size() << endl;// v3动态数组长度为:4
// 清空所有元素
v1.clear();
cout << v1.size(); // 此时长度是0
return 0;
}
vector 的用途
- 节省内存但仍需完成像数组一样的操作(例如题目描述:n <= 1e6,m <= 1e6,n * m <= 1e6)
- 频繁随机访问
第3.2部分:list
list 是什么和它的底层原理
- list 是双向链表
- 底层原理:每个节点包含数据和前后指针
- 节点在内存中不连续,也就是说不能随机访问
list 的优缺点
- 优点:任意位置插入、删除快
- 缺点:随机访问慢
list 的核心用法
#include <bits/stdc++.h>
using namespace std;
int main(){
// 1. 定义和初始化
list<int> l1;// 空list
list<int> l2 = {1,2,3};// list中有3个元素。分别是1 2 3-->初始化链表
// 2.1. 插入元素
// 头部
l1.push_front(1);// [1]
// 尾部
l2.push_back(4);// [1,2,3,4]
// 中间,需要迭代器
list<int>::iterator it = l2.begin();
advance(it, 1); // 移动迭代器到索引1
l2.insert(it, 2);// [1,2,2,3,4]
// 2.2 删除元素,仍然需要迭代器
advance(it, 2);
l2.erase(it); // 删除第三个元素(下标为2),[1 2 3 4]
// 3.访问某个元素
// 范围for+手动维护
int idx = 0;
int mb = 1;// 要访问第2个元素
for (int num : l2){
if (idx == mb){
cout << num << endl;// 最终结果:2
break;
}
idx++;
}
// 4.遍历(迭代器、范围for)
// 要是想知道这项的下标是多少,需要手动维护
// 迭代器方案
int idx1 = 0;
for (list<int>::iterator it1 = l2.begin(); it1 != l2.end(); ++it1) {
cout << *it1 << " " << idx1++ << endl; // 解引用迭代器获取元素
}
// 范围for方案
int idx2 = 0;
for (int num : l2){
cout << num << " " << idx2++ << endl;
}
return 0;
}
list 的用途
- 频繁在任意位置插入、删除元素
- 不需要随机访问但需要双向遍历
第3.3部分:queue
queue 是什么和它的底层原理
- queue 是先进先出队列
- 底层原理:基于其它容器实现
queue 的优缺点
- 优点:首尾操作快
- 缺点:随机访问慢、内存开销略大
queue 的核心用法
#include <bits/stdc++.h>
using namespace std;
//定义:queue<存储的数据类型> 队列的名字
queue<int> q;
int main() {
q.push(1); //入队,插入到队首
// [1]
q.front(); //返回队首元素的值,为1
q.back(); //返回队尾元素的值,为1
q.pop(); //队首出队
// []
q.empty(); //判断是否为空,为true
q.size(); //返回队列中元素个数,为0
//在取队首(front)、取队尾(back)、队首出队(pop)时,一定要先判断队列不为空,否则会爆RE
return 0;
}
queue 的用途
- 排队问题
- 广度优先搜索
第3.4部分:stack
stack 是什么和它的底层原理
- stack 是后进先出栈
- 底层原理:基于其它容器实现
stack 的优缺点
- 优点:首操作快、DFS清楚
- 缺点:仅支持栈顶操作,无法随机访问或遍历元素;有可能栈溢出
stack 的核心用法
#include <bits/stdc++.h>
using namespace std;
//定义:stack<存储的数据类型> 栈的名字
stack<int> s;
int main() {
s.push(1); //入栈,插入栈顶
// [1]
s.top(); //返回栈顶元素的值,为1
s.pop(); //栈顶出队
// []
s.empty(); //判断是否为空,为true
s.size(); //返回栈顶中元素个数,为0
//在取栈顶(top)、出站(pop)时,一定要先判断栈不为空,否则会爆RE
return 0;
}
stack 的用途
- 括号匹配
- 表达式求值
- 撤销操作
- 深度优先搜索
- 初赛有可能考
全部评论 1
d
2天前 来自 河北
0
有帮助,赞一个