一、引言

STL(Standard Template Library)是 C++ 标准库的核心组成部分,其中容器(Containers) 作为数据存储的基础组件,为开发者提供了丰富的数据结构选择。本文将聚焦 STL 容器的核心类型,结合具体 C++ 代码示例详解其特性、用法及适用场景,帮助读者在实际开发中精准选型。

二、序列容器(Sequence Containers)

序列容器按元素插入顺序存储数据,支持按位置访问,是最常用的容器类型。

2.1 std::vector:动态数组

特性:内存连续存储,支持随机访问,尾部插入 / 删除高效,中间插入 / 删除开销大。
适用场景:需要频繁随机访问、尾部操作的场景(如存储动态列表、缓存数据)。

代码示例:
#include <iostream>
#include <vector>
using namespace std;int main() {// 1. 初始化方式vector<int> vec1; // 空vectorvector<int> vec2(5, 10); // 5个元素,每个初始化为10vector<int> vec3 = {1, 2, 3, 4, 5}; // 初始化列表// 2. 尾部插入元素vec1.push_back(6);vec1.push_back(7);// 3. 随机访问([]或at())cout << "vec3[2] = " << vec3[2] << endl; // 输出3cout << "vec3.at(3) = " << vec3.at(3) << endl; // 输出4(带越界检查)// 4. 遍历元素(迭代器)cout << "vec3元素:";for (vector<int>::iterator it = vec3.begin(); it != vec3.end(); ++it) {cout << *it << " ";}cout << endl;// 5. 容量与大小cout << "vec3大小:" << vec3.size() << endl; // 5cout << "vec3容量:" << vec3.capacity() << endl; // 至少5(动态扩容)// 6. 中间插入元素(效率较低)vec3.insert(vec3.begin() + 2, 99); // 在索引2处插入99cout << "插入后vec3[2] = " << vec3[2] << endl; // 输出99return 0;
}

2.2 std::list:双向链表

特性:非连续存储,通过指针连接元素,任意位置插入 / 删除高效,不支持随机访问。
适用场景:需要频繁在中间插入 / 删除元素的场景(如实现链表、队列、邻接表)。

代码示例:
#include <iostream>
#include <list>
using namespace std;int main() {// 初始化列表list<int> lst = {3, 1, 4, 1, 5};// 1. 头部/尾部操作lst.push_front(0); // 头部插入0lst.push_back(6); // 尾部插入6// 2. 遍历(不支持[]访问,需迭代器)cout << "list元素:";for (auto it = lst.begin(); it != lst.end(); ++it) {cout << *it << " ";}cout << endl; // 输出:0 3 1 4 1 5 6// 3. 中间插入/删除auto it = lst.begin();advance(it, 2); // 移动迭代器到第2个元素(值为3的下一个元素1)lst.insert(it, 99); // 在1前插入99cout << "插入后元素:";for (int num : lst) { // 范围for循环cout << num << " ";}cout << endl; // 输出:0 3 99 1 4 1 5 6// 4. 删除指定值的元素lst.remove(1); // 删除所有值为1的元素cout << "删除1后元素:";for (int num : lst) {cout << num << " ";}cout << endl; // 输出:0 3 99 4 5 6return 0;
}

2.3 std::deque:双端队列

特性:分段连续内存,支持两端高效插入 / 删除,随机访问效率略低于 vector。
适用场景:需要频繁在头部和尾部操作的场景(如实现队列、缓冲区)。

代码示例:
#include <iostream>
#include <deque>
using namespace std;int main() {deque<int> dq;// 1. 两端插入dq.push_back(10); // 尾部插入dq.push_front(5); // 头部插入dq.push_back(20);dq.push_front(1);// 2. 随机访问cout << "dq[1] = " << dq[1] << endl; // 输出5cout << "dq.at(2) = " << dq.at(2) << endl; // 输出10// 3. 遍历cout << "deque元素:";for (int num : dq) {cout << num << " ";}cout << endl; // 输出:1 5 10 20// 4. 两端删除dq.pop_front(); // 删除头部元素1dq.pop_back(); // 删除尾部元素20cout << "删除后元素:";for (int num : dq) {cout << num << " ";}cout << endl; // 输出:5 10return 0;
}

三、关联容器(Associative Containers)

关联容器基于键(Key)存储元素,内部通常用红黑树实现,元素自动排序,支持高效查找。

3.1 std::set:有序唯一集合

特性:元素唯一且按升序排列,插入 / 查找 / 删除时间复杂度 O (log n)。
适用场景:需要去重并保持有序的集合(如存储唯一 ID、实现集合运算)。

代码示例:
#include <iostream>
#include <set>
using namespace std;int main() {// 初始化(自动排序+去重)set<int> s = {5, 2, 8, 2, 5, 9};// 1. 插入元素s.insert(3);// 2. 遍历(默认升序)cout << "set元素:";for (int num : s) {cout << num << " ";}cout << endl; // 输出:2 3 5 8 9// 3. 查找元素auto it = s.find(5);if (it != s.end()) {cout << "找到元素:" << *it << endl;} else {cout << "未找到元素" << endl;}// 4. 删除元素s.erase(8); // 删除值为8的元素cout << "删除8后元素:";for (int num : s) {cout << num << " ";}cout << endl; // 输出:2 3 5 9return 0;
}

3.2 std::map:有序键值对映射

特性:键唯一且按升序排列,通过键快速访问值,时间复杂度 O (log n)。
适用场景:需要键值对映射的场景(如字典、配置表、索引表)。

代码示例:
#include <iostream>
#include <map>
#include <string>
using namespace std;int main() {// 初始化键值对(键为int,值为string)map<int, string> student;// 1. 插入元素(三种方式)student[101] = "Alice"; // 下标法student.insert(pair<int, string>(102, "Bob")); // pair插入student.emplace(103, "Charlie"); // emplace(更高效)// 2. 遍历键值对cout << "学生信息:" << endl;for (auto& pair : student) { // 注意用引用避免拷贝cout << "学号:" << pair.first << ",姓名:" << pair.second << endl;}// 输出:// 学号:101,姓名:Alice// 学号:102,姓名:Bob// 学号:103,姓名:Charlie// 3. 查找键对应的值int id = 102;auto it = student.find(id);if (it != student.end()) {cout << id << "对应的姓名:" << it->second << endl; // 输出Bob}// 4. 删除键student.erase(101);cout << "删除101后学号101是否存在:" << (student.count(101) ? "是" : "否") << endl; // 输出否return 0;
}

3.3 std::multiset 与 std::multimap:允许重复键

特性multiset 允许重复元素,multimap 允许重复键,均有序排列。
适用场景:需要存储重复元素 / 键的场景(如统计频率、一对多映射)。

代码示例(multimap):
#include <iostream>
#include <map>
#include <string>
using namespace std;int main() {// 课程-学生映射(一门课对应多个学生)multimap<string, string> course;// 插入重复键course.insert({"Math", "Alice"});course.insert({"Math", "Bob"});course.insert({"Physics", "Charlie"});course.insert({"Math", "David"});// 1. 遍历所有键值对cout << "所有课程学生:" << endl;for (auto& pair : course) {cout << pair.first << ":" << pair.second << endl;}// 2. 查找特定键的所有值string key = "Math";cout << "\n" << key << "的学生:" << endl;auto range = course.equal_range(key); // 获取键为Math的范围for (auto it = range.first; it != range.second; ++it) {cout << it->second << endl; // 输出Alice、Bob、David}return 0;
}

四、无序关联容器(Unordered Associative Containers)

C++11 引入,基于哈希表实现,元素无序,平均插入 / 查找 / 删除时间复杂度 O (1)。

4.1 std::unordered_set:无序唯一集合

特性:元素唯一、无序,哈希表存储,查找效率极高(无排序开销)。
适用场景:只需去重和快速查找,不关心顺序的场景(如黑名单、存在性判断)。

代码示例:
#include <iostream>
#include <unordered_set>
using namespace std;int main() {unordered_set<string> fruits = {"apple", "banana", "orange"};// 1. 插入元素fruits.insert("grape");// 2. 遍历(无序)cout << "无序集合元素:";for (auto& fruit : fruits) {cout << fruit << " ";}cout << endl; // 输出顺序不确定// 3. 快速查找string target = "banana";if (fruits.count(target)) { // count()判断存在性cout << target << " 存在于集合中" << endl;}return 0;
}

4.2 std::unordered_map:无序键值对映射

特性:键唯一、无序,哈希表存储,适合高频查找场景。
适用场景:需要快速键值映射且不关心顺序的场景(如缓存、哈希表)。

代码示例:
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;int main() {// 姓名-年龄映射(无序)unordered_map<string, int> age;age["Alice"] = 20;age["Bob"] = 22;age["Charlie"] = 21;// 1. 遍历(无序)cout << "姓名-年龄:" << endl;for (auto& pair : age) {cout << pair.first << ":" << pair.second << endl;}// 2. 查找效率对比(哈希表 vs 红黑树)// 对于高频查找,unordered_map性能优于mapcout << "Bob的年龄:" << age["Bob"] << endl;return 0;
}

五、容器适配器(Container Adapters)

基于基础容器封装的特殊接口,简化特定场景使用。

5.1 std::stack:栈(LIFO)

特性:后进先出,基于 deque 默认实现,支持push(入栈)、pop(出栈)、top(取栈顶)。
适用场景:表达式求值、括号匹配、深度优先搜索(DFS)。

代码示例:
#include <iostream>
#include <stack>
using namespace std;int main() {stack<int> st;// 入栈st.push(1);st.push(2);st.push(3);// 栈顶元素cout << "栈顶元素:" << st.top() << endl; // 输出3// 出栈st.pop(); // 删除栈顶元素3cout << "出栈后栈顶:" << st.top() << endl; // 输出2// 栈大小cout << "栈大小:" << st.size() << endl; // 输出2return 0;
}

5.2 std::queue:队列(FIFO)

特性:先进先出,基于 deque 默认实现,支持push(入队)、pop(出队)、front(队首)。
适用场景:任务调度、广度优先搜索(BFS)、消息队列。

代码示例:
#include <iostream>
#include <queue>
using namespace std;int main() {queue<string> q;// 入队q.push("任务1");q.push("任务2");q.push("任务3");// 队首元素cout << "队首任务:" << q.front() << endl; // 输出任务1// 出队q.pop(); // 移除任务1cout << "出队后队首:" << q.front() << endl; // 输出任务2// 队列大小cout << "队列大小:" << q.size() << endl; // 输出2return 0;
}

5.3 std::priority_queue:优先队列

特性:元素按优先级排序(默认最大元素优先),基于 vector 默认实现。
适用场景:定时器、任务调度(高优先级先执行)、最大 / 最小堆场景。

代码示例:
#include <iostream>
#include <queue>
using namespace std;int main() {// 最大优先队列(默认)priority_queue<int> maxHeap;maxHeap.push(3);maxHeap.push(1);maxHeap.push(5);cout << "最大堆顶:" << maxHeap.top() << endl; // 输出5// 最小优先队列(通过greater<>实现)priority_queue<int, vector<int>, greater<int>> minHeap;minHeap.push(3);minHeap.push(1);minHeap.push(5);cout << "最小堆顶:" << minHeap.top() << endl; // 输出1return 0;
}

六、容器选型决策指南

容器类型核心特性时间复杂度(插入 / 查找 / 删除)适用场景
vector连续内存,随机访问尾部 O (1),中间 O (n) / O (1)随机访问、尾部操作多
list双向链表,任意位置操作高效O(1) / O(n)频繁中间插入 / 删除
deque双端操作高效,随机访问两端 O (1) / O (1)双端频繁操作
set/map有序,唯一键,红黑树O(log n) / O(log n)有序集合、键值映射,需排序
unordered_set/unordered_map无序,哈希表平均 O (1) / 平均 O (1)高频查找,不关心顺序
stack/queue适配器,LIFO/FIFOO(1)栈 / 队列特定场景
priority_queue优先级排序O(log n)高优先级任务调度

七、总结

STL 容器为 C++ 开发者提供了开箱即用的数据结构解决方案,掌握各类容器的特性和适用场景是编写高效代码的基础。实际开发中需根据访问方式、操作频率、排序需求等因素选型:

  • 需随机访问选vector/deque
  • 需有序且高效查找选set/map
  • 需极致查找性能且无序选unordered_*
  • 需特定数据结构行为选适配器(stack/queue等)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/93271.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/93271.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/93271.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

神经网络 常见分类

&#x1f4da; 神经网络的常见分类方式可以从不同角度来划分&#xff0c;以下是几种主流思路&#xff0c;帮你快速梳理清晰&#xff1a;1️⃣ 按网络结构分类前馈神经网络&#xff08;Feedforward Neural Network, FNN&#xff09; 数据从输入层→隐藏层→输出层单向传递&#…

生产环境Redis缓存穿透与雪崩防护性能优化实战指南

生产环境Redis缓存穿透与雪崩防护性能优化实战指南 在当下高并发场景下&#xff0c;Redis 作为主流缓存组件&#xff0c;能够极大地提升读写性能&#xff0c;但同时也容易引发缓存穿透、缓存击穿及缓存雪崩等问题&#xff0c;导致后端依赖数据库的请求激增&#xff0c;系统稳定…

【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)

&#x1f525;个人主页&#xff1a;艾莉丝努力练剑 ❄专栏传送门&#xff1a;《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题、洛谷刷题、C/C基础知识知识强化补充、C/C干货分享&学习过程记录 &#x1f349;学习方向&#xff1a;C/C方向 ⭐️人…

嵌入式硬件篇---常见的单片机型号

以下是目前常用的单片机型号及其应用场景、优劣势的详细解析&#xff0c;结合最新行业动态和技术特性&#xff0c;帮助你精准匹配需求&#xff1a;一、经典 8 位单片机&#xff1a;低成本入门首选1. 51 系列&#xff08;代表型号&#xff1a;AT89C51、STC89C52&#xff09;应用…

windows下ArcGIS 10.8.2下载安装教程

ArcGIS是由美国环境系统研究所&#xff08;Esri&#xff09;开发的一款功能强大且应用广泛的综合性地理信息系统&#xff08;GIS&#xff09;软件平台&#xff0c;在空间数据的采集、管理、分析、可视化和共享等方面表现出色&#xff0c;是GIS领域的标杆产品。它拥有丰富的功能…

防御保护15

混合密码体系 --- 数字信封 逻辑 --- 先用快速的对称密钥来对消息进行加密&#xff0c;保证数据的机密性。然后只需要保证对称密钥的机密性即可&#xff0c;使用公钥密钥体系来对对称秘钥消息进行加密。身份认证和数据认证技术 Hash散列 指纹 ---> 单向散列函数 Hash --->…

Linux上管理Java的JDK版本

1.alternatives简介alternatives是 Linux 系统&#xff08;尤其是 ​​RHEL/CentOS/Fedora​​ 等基于 RPM 的发行版&#xff09;中用于管理​​同一软件多个版本​​的系统工具。它通过维护符号链接&#xff08;软链接&#xff09;的层级结构&#xff0c;帮助用户在不冲突的情…

webrtc编译arm/arm64

webrtc版本 m125版本 编译arm sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf //下载失败,需要多次尝试 python3 build/linux/sysroot_scripts/install-sysroot.py --arch=arm //python3 bui

【读论文】医疗AI大模型:百川开源Baichuan-M2

1. 引言 最新百川开源了一个可以和openai新模型掰手腕的医疗垂直大模型:Baichuan-M2在HealthBench基准上取值60.1的高分,超过了gpt-oss-120b。这次一起回顾下百川给的技术报告。 2. Baichuan-M2概览:“模型+系统” Baichuan-M2的成功源于一套精心设计的、端到端的训练与优…

OBOO鸥柏丨75寸/86平板企业办公会议触控一体机核心国产化品牌招投标参数

OBOO鸥柏整机参数要求&#xff1a;55寸/65寸/75寸/85-86寸/98寸/100寸/110寸/115寸智能会议平板教学触控一体机/智慧黑板触摸屏参数要求。系统可灵活选择如&#xff1a;支持安卓&#xff08;Android&#xff09;&#xff0c;Windows可选择。并在KylinOS银河麒麟操作系统、统信U…

DCT域信息隐藏中超参数影响的深度解析:从理论到实践的完整指南

摘要 随着数字媒体技术的飞速发展,信息隐藏技术在版权保护、内容认证和隐私保护等领域发挥着越来越重要的作用。离散余弦变换(DCT)域作为信息隐藏的经典载体,因其与JPEG压缩标准的天然兼容性而备受关注。然而,DCT域信息隐藏的效果很大程度上取决于各种超参数的精心调节,…

YOLOv8环境配置命令

【YOLOv8】一小时掌握&#xff0c;从0开始搭建部署YOLOv8系列教程&#xff0c;安装推理自定义数据集训练与搭建_哔哩哔哩_bilibili【YOLOv8】一小时掌握&#xff0c;从0开始搭建部署YOLOv8系列教程&#xff0c;安装推理自定义数据集训练与搭建共计10条视频&#xff0c;包括&…

Maven私服配置模版

参考课程: 【黑马程序员 JavaWeb开发教程】 [https://www.bilibili.com/video/BV1m84y1w7Tb] ZZHow(ZZHow1024)Maven 的 settings.xml 配置文件中&#xff08;从私服下载项目到本地&#xff09; 在 servers 标签中&#xff0c;配置访问私服的个人凭证&#xff08;访问的用户名和…

《智能体(Agent)速记指南》

《智能体&#xff08;Agent&#xff09;速记指南》 &#x1f4d8; 一句话核心&#xff1a;智能体 会判断 会用工具&#xff0c;能独立完成任务的系统。一、智能体到底是什么&#xff1f; ✅ 一句话定义&#xff1a;能独立跑完一个完整任务&#xff0c;不用人盯着。 ⚠️ 别搞…

BERT模型引入及详解

BERT模型引入及详解 参考 视频: ELMo 模型&#xff08;双向 LSTM 模型解决词向量多义问题 博客&#xff1a; BERT模型BERT详解&#xff1a;概念、原理与应用一文读懂BERT ELMo模型 参考: 视频: ELMo模型&#xff08;双向LSTM模型解决词向量多义问题&#xff09; 博客: 【…

开源 Arkts 鸿蒙应用 开发(十六)自定义绘图控件--波形图

文章的目的为了记录使用Arkts 进行Harmony app 开发学习的经历。本职为嵌入式软件开发&#xff0c;公司安排开发app&#xff0c;临时学习&#xff0c;完成app的开发。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; 开源 Arkts …

【linux】自定义shell——bash命令行解释器小程序

小编个人主页详情<—请点击 小编个人gitee代码仓库<—请点击 linux系列专栏<—请点击 倘若命中无此运&#xff0c;孤身亦可登昆仑&#xff0c;送给屏幕面前的读者朋友们和小编自己! 目录前言一、交互问题&#xff0c;获取命令行二、字串的分隔问题&#xff0c;解析命…

【Python】Python爬虫学习路线

文章目录Python爬虫学习路线&#xff1a;从入门到实战的全景指南一、地基&#xff1a;Python核心基础1. 基础语法与数据结构2. 面向对象编程&#xff08;OOP&#xff09;3. 正则表达式&#xff08;Regex&#xff09;4. 模块与包管理二、工具链&#xff1a;Python爬虫核心库1. 网…

VUE+SPRINGBOOT从0-1打造前后端-前后台系统-用户管理

在现代Web应用开发中&#xff0c;前后端分离架构已经成为主流模式。本文将通过一个完整的用户管理系统案例&#xff0c;详细介绍如何使用Vue.js Element UI构建前端界面&#xff0c;结合Spring Boot实现后端服务&#xff0c;实现前后端分离开发。该系统包含用户信息的增删改查…

基于uni-app+vue3实现的微信小程序地图范围限制与单点标记功能实现指南

一、功能概述本文将分步骤讲解如何使用uni-app框架在微信小程序中实现以下功能&#xff1a;显示基础地图绘制特定区域范围&#xff08;以郑州市为例&#xff09;实现点击地图添加标记点限制标记点只能在指定区域内添加显示选中位置的坐标信息二、分步骤实现步骤1&#xff1a;搭…