当前位置: 首页 > news >正文

C++ 容器入门:从初始化到常用操作全解析

对于 C++ 新手来说,容器是编写高效代码的基础工具。容器本质上是用于存储和管理数据的类模板,C++ 标准库(STL)提供了多种容器,每种容器都有独特的底层结构和适用场景。本文将按类别介绍常用容器,包括初始化、遍历和核心操作,帮助新手快速上手。

一、容器的分类

STL 容器主要分为四大类,新手需先明确各类容器的核心特点:

类别代表容器核心特点适用场景
序列式容器vector、list、deque数据按插入顺序存储,可通过索引 / 迭代器访问需按顺序存储、频繁访问或修改数据
关联式容器map、set、multimap、multiset数据自动排序(基于红黑树),通过键值访问需快速查找、排序或去重数据
无序关联式容器unordered_map、unordered_set数据无序存储(基于哈希表),通过键值访问需超快速查找(O (1) 复杂度),不关心排序
适配器容器stack、queue、priority_queue基于其他容器封装,提供特定操作接口需特定数据结构(如栈、队列)的场景

二、序列式容器:按顺序存储数据

序列式容器是新手最易理解的类型,数据存储顺序与插入顺序一致,支持直接访问。

1. vector:动态数组(最常用)

底层结构:动态数组(内存连续),支持快速随机访问,但插入 / 删除尾部外元素效率低。

核心优势:访问速度快(O (1)),内存连续,适合频繁读操作。

(1)初始化方式
#include <vector>
using namespace std;// 1. 空vector
vector<int> v1;// 2. 初始化n个默认值(int默认0,string默认空)
vector<int> v2(5);       // 存储:[0,0,0,0,0]
vector<string> v3(3);    // 存储:["","",""]// 3. 初始化n个指定值
vector<int> v4(4, 10);   // 存储:[10,10,10,10]// 4. 用数组/其他容器初始化
int arr[] = {1,2,3,4};
vector<int> v5(arr, arr+4);          // 用数组初始化(左闭右开)
vector<int> v6(v5.begin(), v5.end());// 用其他vector初始化
vector<int> v7 = {1,2,3,4,5};        // C++11后支持列表初始化(推荐)
(2)遍历方式
// 1. 下标访问(类似数组,仅vector和deque支持)
for (int i = 0; i < v7.size(); i++) {cout << v7[i] << " ";  // 输出:1 2 3 4 5
}// 2. 迭代器(通用遍历方式,所有容器支持)
vector<int>::iterator it;  // 普通迭代器(可修改数据)
for (it = v7.begin(); it != v7.end(); it++) {*it += 1;              // 修改数据(每个元素+1)cout << *it << " ";    // 输出:2 3 4 5 6
}// 3. 范围for循环(C++11后,简洁推荐)
for (int num : v7) {cout << num << " ";    // 输出:2 3 4 5 6
}
// 若需修改数据,加引用:for (int& num : v7) { num +=1; }
(3)常用方法
方法功能示例
size()返回元素个数int len = v7.size();(结果为 5)
push_back(x)在尾部添加元素 xv7.push_back(6);(v7 变为 [2,3,4,5,6,6])
pop_back()删除尾部元素(无返回)v7.pop_back();(v7 变回 [2,3,4,5,6])
empty()判断是否为空(空返回 true)if (v7.empty()) { … }
clear()清空所有元素v7.clear();(size 变为 0,内存不释放)
insert(pos, x)在迭代器 pos 位置插入 xv7.insert(v7.begin()+2, 9);(在第 3 位插入 9)
erase(pos)删除迭代器 pos 位置元素v7.erase(v7.begin()+2);(删除第 3 位元素)

2. list:双向链表

底层结构:双向链表(内存不连续),插入 / 删除效率高(O (1)),但不支持随机访问。

核心优势:适合频繁在中间插入 / 删除数据(如链表操作)。

(1)初始化与 vector 类似
#include <list>
list<int> l1;                  // 空list
list<int> l2(3, 5);            // 3个5:[5,5,5]
list<int> l3 = {1,2,3,4};      // 列表初始化
(2)遍历:仅支持迭代器和范围 for
// 不支持下标访问!必须用迭代器
for (list<int>::iterator it = l3.begin(); it != l3.end(); it++) {cout << *it << " ";  // 输出:1 2 3 4
}// 范围for(推荐)
for (int num : l3) {cout << num << " ";
}
(3)独特常用方法

除size()、empty()、clear()外,list 有链表专属方法:

方法功能示例
push_front(x)在头部添加 xl3.push_front(0);(l3 变为 [0,1,2,3,4])
pop_front()删除头部元素l3.pop_front();(l3 变回 [1,2,3,4])
insert(pos, x)在 pos 位置插入 x(效率高)l3.insert(l3.begin()+1, 9);(无需移动元素)
remove(x)删除所有值为 x 的元素l3.remove(2);(删除所有 2)

3. deque:双端队列

底层结构:分段连续内存(类似 “动态数组的数组”),支持头部和尾部快速操作。

核心优势:兼顾 vector 的随机访问和 list 的首尾操作效率,适合 “队列” 场景。

关键特点
  • 支持下标访问(deque[0])和迭代器遍历;
  • 常用方法:push_front(x)、push_back(x)、pop_front()、pop_back()(首尾操作均为 O (1));
  • 初始化和遍历与 vector 完全一致,新手可先类比 vector 学习。

三、关联式容器:自动排序的 “字典”

关联式容器基于红黑树实现,数据会自动按 “键值” 排序,支持快速查找(O (log n))。核心是 “键(key)” 和 “值(value)” 的映射关系。

1. map:键值对映射(键唯一)

核心特点:每个元素是pair<key, value>(键值对),键不能重复,自动按键排序(默认升序)。

适用场景:需要 “字典” 功能(如姓名→成绩、ID→信息)。

(1)初始化方式
#include <map>
using namespace std;// 1. 空map(键int,值string)
map<int, string> m1;// 2. 插入键值对(3种方式)
m1[1] = "Alice";          // 下标插入(键1对应值Alice)
m1.insert(pair<int, string>(2, "Bob"));  // pair插入
m1.insert({3, "Charlie"});               // C++11列表插入(推荐)// 3. 直接初始化
map<int, string> m2 = {{1, "Alice"},{2, "Bob"},{3, "Charlie"}
};
(2)遍历方式
// 1. 迭代器(需访问pair的first和second)
map<int, string>::iterator it;
for (it = m2.begin(); it != m2.end(); it++) {// it->first是键,it->second是值cout << "ID:" << it->first << " Name:" << it->second << endl;
}// 2. 范围for(推荐,用auto简化类型)
for (auto& pair : m2) {  // auto自动识别为pair<int, string>cout << "ID:" << pair.first << " Name:" << pair.second << endl;
}
(3)常用方法
方法功能示例
size()返回键值对个数int len = m2.size();(结果为 3)
find(key)查找键为 key 的元素,返回迭代器auto it = m2.find(2);(找到返回对应迭代器)
count(key)统计键为 key 的个数(map 中仅 0 或 1)if (m2.count(2) > 0) { … }(判断键是否存在)
erase(key)删除键为 key 的元素m2.erase(2);(删除 ID=2 的键值对)
clear()清空所有元素m2.clear();

2. set:仅存储键(键唯一且排序)

核心特点:仅存储 “键”(无值),键唯一且自动排序,本质是 “去重 + 排序” 的集合。

适用场景:需要去重或排序的数据(如统计不重复的成绩)。

关键操作(类比 map)
#include <set>
set<int> s = {3,1,2,3};  // 初始化,自动去重并排序为[1,2,3]// 遍历
for (int num : s) {cout << num << " ";  // 输出:1 2 3
}// 常用方法
s.insert(4);             // 插入4(变为[1,2,3,4])
s.erase(2);              // 删除2(变为[1,3,4])
if (s.find(3) != s.end()) {  // 查找3是否存在cout << "3 exists";
}

3. multimap/multiset:允许键重复

  • multimap:键可重复,其他与 map 一致(如按键排序);
  • multiset:键可重复,其他与 set 一致;
  • 区别:count(key)可能返回大于 1 的值,find(key)返回第一个匹配的键。

四、无序关联式容器:快速查找的 “哈希表”

无序关联式容器基于哈希表实现,数据无序存储,但查找效率极高(平均 O (1)),适合 “只查不改” 或 “频繁查找” 场景。

核心容器:unordered_map和unordered_set,用法与map/set完全一致,仅两点区别:

  1. 数据无序(遍历顺序与插入顺序无关);
  2. 不支持按键排序相关操作(如lower_bound)。

示例(unordered_map):

#include <unordered_map>
unordered_map<int, string> um = {{1, "Alice"},{2, "Bob"}
};// 遍历(顺序不确定,可能是2→1或1→2)
for (auto& pair : um) {cout << pair.first << ":" << pair.second << endl;
}// 查找效率比map高(哈希表直接定位)
auto it = um.find(1);  // 平均O(1)时间

五、适配器容器:封装后的 “专用工具”

适配器容器不直接存储数据,而是基于其他容器(如 vector、deque)封装,提供特定操作接口,新手需掌握核心用法。

1. stack:栈(先进后出)

底层依赖:默认基于 deque,支持push(入栈)、pop(出栈)、top(取栈顶)。

#include <stack>
stack<int> st;st.push(1);  // 入栈:[1]
st.push(2);  // 入栈:[1,2]
cout << st.top();  // 取栈顶:2
st.pop();          // 出栈:[1]
cout << st.size(); // 大小:1

2. queue:队列(先进先出)

底层依赖:默认基于 deque,支持push(入队)、pop(出队)、front(取队首)。

#include <queue>
queue<int> q;q.push(1);  // 入队:[1]
q.push(2);  // 入队:[1,2]
cout << q.front();  // 取队首:1
q.pop();            // 出队:[2]

3. priority_queue:优先队列(自动排序)

底层依赖:默认基于 vector,数据自动按 “大顶堆” 排序(队首是最大值)。

#include <queue>
priority_queue<int> pq;pq.push(3);  // 入队:[3]
pq.push(1);  // 入队后排序:[3,1]
pq.push(2);  // 入队后排序:[3,2,1]
cout << pq.top();  // 取最大值:3
pq.pop();          // 出队后排序:[2,1]

六、新手选择容器的核心原则

  1. 频繁访问数据:选 vector(随机访问快);
  2. 频繁插入 / 删除中间元素:选 list(链表无需移动数据);
  3. 需要队列 / 栈操作:选 queue/stack(适配器简单易用);
  4. 需要字典功能(键值对)
  • 需排序:选 map;
  • 不需排序但要快查:选 unordered_map;
  1. 需要去重
  • 需排序:选 set;
  • 不需排序但要快查:选 unordered_set。

通过以上内容,新手可掌握 C++ 常用容器的核心用法。建议结合实际代码练习(如用 vector 存储学生成绩、用 map 实现字典查询),逐步熟悉各类容器的适用场景,为后续学习算法和数据结构打下基础。

http://www.dtcms.com/a/553435.html

相关文章:

  • 飞致云开源社区月度动态报告(2025年10月)
  • 企业网站建设的步骤网站维护包括哪些
  • 网站建设缺乏个性网站如何优化关键词
  • GNN变体
  • SpringMVC基础入门
  • XiangJsonCraft v1.1.0发布:JSON配置网页的终极进化,支持所有CSS选择器!
  • UVa 12670 Counting Ones
  • C++17(新特性)
  • 韩国风网站什么网站有做册子版
  • day58-Shell编程(第四部分)
  • 用AI写了一个文档拼音标注工具 中文+拼音一键生成
  • 做网站还有意义同样是div 怎么有些网站收录少 有些多
  • 企必搜做网站做国际物流在哪些网站找客户
  • 移动端适配完全指南:从基础到最佳实践
  • 使用JMeter进行API性能压测(执行篇)
  • IntelliJ IDEA 远程调试(Remote Debugging)教程
  • 网站服务器++免费做电子手抄报的网站
  • 单页网站的优点网络公司是做什么的?
  • 阿瓦隆 Q 90T矿机:低功耗高效挖矿,是否值得选择?
  • 印度实时股票数据源接口对接文档-IPO新股、k线数据
  • HTTPS接口国密安全设计(含防重放设计)
  • 网站设计公司(信科网络)中国制造网外贸平台怎么注册
  • 网站模版如何去除title版权信息499元做网站
  • 武进建设局网站首页胖鼠wordpress
  • 机器学习第一阶段
  • Linux内核RDMA用户态内存映射机制深度解析:零拷贝高性能的基石
  • 组态软件和实时数据库区别大吗?
  • SpringBoot】Spring Boot 项目的打包配置
  • 递归专题5 - FloodFill算法专题
  • 系统架构设计师论文-论软件架构的复用