STL(Standard Template Library)容器

news/2025/3/10 15:22:38/文章来源:https://www.cnblogs.com/zyihan-crz/p/18762769

STL(Standard Template Library)容器

vector容器 — 动态数组

简介

​ vector 是一个序列容器,它允许用户在容器的末尾快速地添加或删除元素。与数组相比,vector提供了更多的功能,如自动调整大小,随机访问等。

语法

在C++中使用vector需要包含头文件“ #include ”和“ using namespace std; ”

以下是一些基本语法:

声明vector:

vector<int> myVector; //声明一个int类型的vector myVector

添加元素:

myVector.push_back(10); //在末尾添加一个元素10

访问元素:

int a = myVector[0]; //将0号位的元素赋给a
cout << myVector[0]; //输出0号位的元素

获取元素数量:

int size_myVector = myVector.size();

清空vector:

myVector.clear();

声明与初始化

vector需要制定元素类型,可通过多种方式初始化:

#include <iostream>
#include <vector>
using namespace std;
int main() {vector<int> vec1;                  // 空的vectorvector<int> vec2(5);               // 长度为5的vector,元素默认初始化vector<int> vec3(5, 10);           // 长度为5的vector,元素值均为10vector<int> vec4 = {1, 2, 3, 4};   // 使用初始化列表初始化return 0;
}

实例

#include <iostream>
#include <vector>
using namespace std;int main() {// 声明一个存储整数的 vectorvector<int> numbers;// 添加元素numbers.push_back(10);numbers.push_back(20);numbers.push_back(30);// 输出 vector 中的元素cout << "vector中的元素: ";for (int i = 0; i < numbers.size(); ++i) {cout << numbers[i] << " ";}cout << endl;// 添加更多元素numbers.push_back(40);numbers.push_back(50);// 再次输出 vector 中的元素cout << "在添加元素之后, vector中的元素: ";for (int i = 0; i < numbers.size(); ++i) {cout << numbers[i] << " ";}cout << endl;// 访问特定元素cout << "第一个元素: " << numbers[0] << endl;// 清空 vectornumbers.clear();// 检查 vector 是否为空if (numbers.empty()) {cout << "这个vector是空的" << endl;}return 0;
}

运行结果:

vector中的元素: 10 20 30 
在添加元素之后, vector中的元素: 10 20 30 40 50 
第一个元素: 10
这个vector是空的

常用的成员函数

函数

函数 说明
push_back(const T& val) 在末尾添加元素
pop_back() 删除末尾元素
at(size_t pos) 返回指定位置的元素,带边界检查
operator[ ] 返回指定位置的元素,不带边界检查
front() 返回第一个元素
back() 返回最后一个元素
data() 返回指向底层数组的指针
size() 返回当前元素数量
capacity() 返回当前分配的容量
reserve(size_t n) 预留至少n个元素的储存空间
resize(size_t n) 将元素数量调整为n
clear() 清空所有元素
insert(iterator pos, val) 在指定位置插入元素
erase(iterator pos) 删除指定位置的元素
begin()/end() 返回起始/结束迭代器

实例

1.基本操作
#include <iostream>
#include <vector>
using namespace std;int main() {vector<int> vec = {1, 2, 3, 4, 5};// 输出所有元素cout << "vector中的元素: ";for (int i = 0; i < vec.size(); ++i) {cout << vec[i] << " ";}cout << endl;// 获取第一个和最后一个元素cout << "第一个元素: " << vec.front() << endl;cout << "最后一个元素: " << vec.back() << endl;return 0;
}

运行结果:

vector中的元素: 1 2 3 4 5 
第一个元素: 1
最后一个元素: 5
2.动态增加和删除元素
#include <iostream>
#include <vector>
using namespace std;int main() {vector<int> vec;vec.push_back(10);vec.push_back(20);vec.push_back(30);cout << "vector元素数量: " << vec.size() << endl;cout << "vector当前分配的容量: " << vec.capacity() << endl;// 删除最后一个元素vec.pop_back();cout << "删除最后一个元素后的vector大小: " << vec.size() << endl;return 0;
}

运行结果:

vector元素数量: 3
vector当前分配的容量: 4
删除最后一个元素后的vector大小: 2
3.边界检查和安全访问
#include <iostream>
#include <vector>
using namespace std;int main() {vector<int> vec = {1, 2, 3};try {cout << vec.at(2) << endl;  // 正常输出cout << vec.at(5) << endl;  // 超出范围,抛出异常} catch (const out_of_range& e) {cout << "Exception: " << e.what() << endl;}return 0;
}

运行结果:

vector元素数量: 3
vector当前分配的容量: 4
删除最后一个元素后的vector大小: 2
4.预分配容量
#include <iostream>
#include <vector>
using namespace std;int main() {vector<int> vec;vec.reserve(10);  // 预留容量,避免频繁分配内存for (int i = 0; i < 10; ++i) {vec.push_back(i);cout << "push_back(" << i << ")之后vec当前分配的容量: " << vec.capacity() << endl;}return 0;
}

运行结果:

push_back(0)之后vec当前分配的容量: 10
push_back(1)之后vec当前分配的容量: 10
push_back(2)之后vec当前分配的容量: 10
push_back(3)之后vec当前分配的容量: 10
push_back(4)之后vec当前分配的容量: 10
push_back(5)之后vec当前分配的容量: 10
push_back(6)之后vec当前分配的容量: 10
push_back(7)之后vec当前分配的容量: 10
push_back(8)之后vec当前分配的容量: 10
push_back(9)之后vec当前分配的容量: 10

队列 — queue

C++ 标准库中的 头文件提供了队列(Queue)数据结构的实现。队列是一种先进先出(FIFO, First In First Out)的数据结构,它允许在一端添加元素(称为队尾),并在另一端移除元素(称为队首)

队列是一种线性数据结构,它遵循以下规则:

1.元素只能从队尾添加
2.元素只能从队首移除

语法

#include <queue>// 声明队列
std::queue<Type> q;

常用操作

队列提供了以下常用操作:

empty(): 检查队列是否为空
size(): 返回队列中的元素数量
front(): 返回队首元素的引用
back(): 返回队尾元素的引用
push(): 在队尾添加一个元素
pop(): 移除队首元素

实例

#include <iostream>
#include <queue>int main() {// 创建一个整数队列std::queue<int> q;// 向队列中添加元素q.push(10);q.push(20);q.push(30);// 打印队列中的元素数量std::cout << "队列中的元素数量: " << q.size() << std::endl;// 打印队首元素std::cout << "队首元素: " << q.front() << std::endl;// 打印队尾元素std::cout << "队尾元素: " << q.back() << std::endl;// 移除队首元素q.pop();std::cout << "移除队首元素后,队首元素: " << q.front() << std::endl;// 再次打印队列中的元素数量std::cout << "队列中的元素数量: " << q.size() << std::endl;return 0;
}

运行结果:

队列中的元素数量: 3
队首元素: 10
队尾元素: 30
移除队首元素后,队首元素: 20
队列中的元素数量: 2

C++ 的 标准库提供了一种方便的方式来实现队列数据结构。通过使用队列,我们可以有效地管理需要按照特定顺序处理的元素集合。希望这篇文章能帮助初学者更好地理解和使用 C++ 中的队列。

注意事项

​ 队列不允许随机访问元素,即不能直接通过索引访问队列中的元素
​ 队列的实现通常使用链表或动态数组,这取决于具体的实现

链表(双向链表)— list

简介

list是 C++ 标准模板库(STL)中的一个序列容器,它允许在容器的任意位置快速插入和删除元素。与数组或向量(vector)不同,list不需要在创建时指定大小,并且可以在任何位置添加或删除元素,而不需要重新分配内存。

语法

基本操作:

包含头文件:#include

声明列表:list mylist; ,其中T是储存在列表中的元素类型(如int,char,double…)

插入元素:mylist.push_back(value);

删除元素:mylist.pop_back(); 或 mylist.erase(iterator);

访问元素:mylist.front(); 和 mylist.begin();

遍历列表:使用迭代器 for(auto it = mylist.begin(); it != mylist.end(); ++ it)

特点

双向迭代 :list提供了双向迭代器,可以向前和向后遍历元素

动态大小 :与数组不同,list的大小可以动态变化,不需要预先分配固定大小的内存

快速插入和删除 :可以在列表的任何位置快速插入或删除元素,而不需要像向量那样移动大量元素

声明与初始化

#include <iostream>
#include <list>
using namespace std;
int main() {list<int> lst1;                  // 空的listlist<int> lst2(5);               // 包含5个默认初始化元素的listlist<int> lst3(5, 10);           // 包含5个元素,每个元素为10list<int> lst4 = {1, 2, 3, 4};   // 使用初始化列表return 0;
}

实例

#include <iostream>
#include <list>int main() {// 创建一个整数类型的列表std::list<int> numbers;// 向列表中添加元素numbers.push_back(10);numbers.push_back(20);numbers.push_back(30);// 访问并打印列表的第一个元素std::cout << "第一个元素: " << numbers.front() << std::endl;// 访问并打印列表的最后一个元素std::cout << "最后一个元素: " << numbers.back() << std::endl;// 遍历列表并打印所有元素std::cout << "List的所有元素: ";for (auto it = numbers.begin(); it != numbers.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;// 删除列表中的最后一个元素numbers.pop_back();// 再次遍历列表并打印所有元素std::cout << "在删除最后一个元素后List的所有元素: ";for (auto it = numbers.begin(); it != numbers.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;return 0;
}

运行结果:

第一个元素: 10
最后一个元素: 30
List的所有元素: 10 20 30 
在删除最后一个元素后List的所有元素: 10 20 

成员函数

函数 说明
push_back(const T& val) 在链表末尾插入元素
push_front(const T& val) 在链表头部添加元素
pop_back() 删除链表末尾的元素
pop_front() 删除链表头部的元素
insert(iterator pos, val) 在指定位置插入元素
erase(iterator pos) 删除指定位置的元素
clear() 清空所有元素
size() 返回链表中的元素数量
empty() 检查链表是否为空
front() 返回链表第一个元素
back() 返回链表最后一个元素
remove(const T& val) 删除所有等于指定值的元素
sort() 对链表中的元素进行排序
merge(list& other) 合并另一个已排序的链表
reverse() 反转链表
begin()/end() 返回链表的起始/结束迭代器

实例

1.基本操作
#include <iostream>
#include <list>int main() {std::list<int> lst = {10, 20, 30};// 插入和删除元素lst.push_front(5);           // 在头部插入5lst.push_back(40);           // 在尾部插入40lst.pop_front();             // 删除头部元素lst.pop_back();              // 删除尾部元素// 输出链表内容std::cout << "链表元素: ";for (const auto& elem : lst) {std::cout << elem << " ";}std::cout << std::endl;return 0;
}

运行结果:

链表元素: 10 20 30 
2.插入和删除特定位置的元素
#include <iostream>
#include <list>int main() {std::list<int> lst = {1, 2, 3, 4, 5};auto it = lst.begin();std::advance(it, 2);          // 移动迭代器到第3个元素(值为3)lst.insert(it, 10);           // 在第3个元素前插入10lst.erase(it);                // 删除第3个元素// 输出链表内容std::cout << "链表元素: ";for (const auto& elem : lst) {std::cout << elem << " ";}std::cout << std::endl;return 0;
}

运行结果:

链表元素: 1 2 10 4 5 
3.排序和去重
#include <iostream>
#include <list>int main() {std::list<int> lst = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};lst.sort();                    // 排序lst.unique();                  // 删除相邻重复元素// 输出链表内容std::cout << "排序去重后的链表: ";for (const auto& elem : lst) {std::cout << elem << " ";}std::cout << std::endl;return 0;
}

运行结果:

排序去重后的链表: 1 2 3 4 5 6 9 
4.合并和反转
#include <iostream>
#include <list>int main() {std::list<int> lst1 = {1, 3, 5, 7};std::list<int> lst2 = {2, 4, 6, 8};lst1.merge(lst2);              // 合并两个已排序的链表lst1.reverse();                // 反转链表// 输出链表内容std::cout << "合并反转后的链表: ";for (const auto& elem : lst1) {std::cout << elem << " ";}std::cout << std::endl;return 0;
}

运行结果;

合并反转后的链表: 8 7 6 5 4 3 2 1 

注意事项

的元素是按插入顺序存储的,而不是按元素值排序。
​ 由于 的元素存储在不同的内存位置,所以它不适合需要随机访问的场景。
​ 与向量相比, 的内存使用效率较低,因为每个元素都需要额外的空间来存储指向前后元素的指针。

栈 — stack

在 C++ 中,标准库提供了多种容器和算法来帮助开发者更高效地编写程序。

是 C++ 标准模板库(STL)的一部分,它实现了一个后进先出(LIFO,Last In First Out)的数据结构。这种数据结构非常适合于需要"最后添加的元素最先被移除"的场景。

容器适配器提供了一个栈的接口,它基于其他容器(如 deque 或 vector)来实现。栈的元素是线性排列的,但只允许在一端(栈顶)进行添加和移除操作。

基本操作

push(): 在栈顶添加一个元素
pop(): 移除栈顶元素
top(): 返回栈顶元素的引用,但不移除它
empty(): 检查栈是否为空
size(): 返回栈中元素的数量

语法

#include <iostream>
#include <stack>int main() {std::stack<int> s;// 向栈中添加元素s.push(10);s.push(20);s.push(30);// 打印栈顶元素std::cout << "栈顶元素是: " << s.top() << std::endl; // 移除栈顶元素s.pop();std::cout << "移除栈顶元素后,栈顶元素是: " << s.top() << std::endl; // 检查栈是否为空if (!s.empty()) {std::cout << "这个栈不是空的" << std::endl; }// 打印栈的大小std::cout << "栈的大小(元素数量)为: " << s.size() << std::endl; // 继续移除元素s.pop();s.pop();// 检查栈是否为空if (s.empty()) {std::cout << "这个栈是空的" << std::endl; }return 0;
}

运行结果:

栈顶元素是: 30
移除栈顶元素后,栈顶元素是: 20
这个栈不是空的
栈的大小(元素数量)为: 2
这个栈是空的

注意事项

不提供直接访问栈中元素的方法,只能通过 top() 访问栈顶元素
​ 尝试在空栈上调用 top() 或 pop() 将导致未定义行为
的底层容器可以是任何支持随机访问迭代器的序列容器,如 vector 或 deque

map容器

在 C++ 中, 是标准模板库(STL)的一部分,它提供了一种关联容器,用于存储键值对(key-value pairs)。

map 容器中的元素是按照键的顺序自动排序的,这使得它非常适合需要快速查找和有序数据的场景。

定义和特性

键值对:map 存储的是键值对,其中每个键都是唯一的。
排序:map 中的元素按照键的顺序自动排序,通常是升序。
唯一性:每个键在 map 中只能出现一次。
双向迭代器:map 提供了双向迭代器,可以向前和向后遍历元素。

基本语法

包含头文件:

#include <map>

声明map容器:

std::map<key_type, value_type> myMap;

​ key_type 是键的类型。
​ value_type 是值的类型。

插入元素:

myMap[key] = value;

访问元素:

value = myMap[key];

遍历map:

for (std::map<key_type, value_type>::iterator it = myMap.begin(); it != myMap.end(); ++it) {std::cout << it->first << " => " << it->second << std::endl;
}

实例

下面是一个使用 map 的简单实例,我们将创建一个 map 来存储员工的姓名和他们的年龄,并遍历这个 map 来打印每个员工的姓名和年龄。

#include <iostream>
#include <map>
#include <string>int main() {// 创建一个 map 容器,存储员工的姓名和年龄std::map<std::string, int> employees;// 插入员工信息employees["Alice"] = 30;employees["Bob"] = 25;employees["Charlie"] = 35;// 遍历 map 并打印员工信息for (std::map<std::string, int>::iterator it = employees.begin(); it != employees.end(); ++it) {std::cout << it->first << " 是 " << it->second << " 岁. " << std::endl;}return 0;
}

运行结果:

Alice 是 30 岁. 
Bob 是 25 岁. 
Charlie 是 35 岁.

看到这个你是不是联想到了结构体?

hhh,这两个有相似的地方也有不同的地方 ,注意自己总结区分哦

进阶用法

检查键是否存在:

if (myMap.find(key) != myMap.end()) {// 键存在
}

删除元素:

myMap.erase(key);

清空map:

myMap.clear();

获取map大小:

size_t size = myMap.size(); //size_t是一种没有符号的整数类型

使用自定义比较函数:

#include <map>
#include <string>
#include <functional>bool myCompare(const std::string& a, const std::string& b) {return a < b;
}int main() {std::map<std::string, int, std::function<bool(const std::string&, const std::string&)>> myMap(myCompare);// 其他操作...return 0;
}

map 是 C++ STL 中一个非常有用的容器,特别适合需要快速查找和有序数据的场景

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

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

相关文章

Nginx 常用功能,反向代理笔记

前言 本文是runoob教程的搬运,稍微修改了原文中的一些错误拼写的问题,顺便对一些概念进行了更详细的解释,欢迎批评指正!Nginx常用功能Http代理,反向代理:作为web服务器最常用的功能之一,尤其是反向代理。 这里我给来2张图,对正向代理与反向代理做个诠释,具体细节,大家…

Oracle 19c 数据库实战:从单机部署到 DG 高可用架构搭建

前言:在当今数字化时代,数据已成为企业最宝贵的资产之一。而数据库作为数据存储和管理的核心工具,其重要性不言而喻。Oracle 数据库作为全球领先的商业数据库管理系统,以其卓越的性能、可靠性和强大的功能,广泛应用于企业的关键业务系统中。无论是大型企业的 ERP、CRM 系统…

002TypeScript开发实战

如果读取不到,情况下: 1、建好项目后我们在这里写一个ts语法,让项目跑起来npm run dev 2、在src中新建文件demo.vue

拯救你的排版噩梦,搞定Deepseek到WPS的完美转换!

我们在使用DeepSeek时,好不容易生成的文案复制到WPS之后,排版却全部乱掉了。别急,今天教你一招,让排版从此不再乱!第一步:下载LibreOffice。打开这个网址:http://www.libreoffice.org 点击顶部的“Download”,选择第一个菜单,然后点击黄色按钮开始下载。如果觉得浏览…

Deepseek学习随笔(16)--- 腾讯研究院发布:AI图景解码50个年度关键词(附网盘链接)

随着人工智能技术的迅猛发展,AI正在深刻改变我们的生活和工作方式。腾讯研究院发布的《AI图景解码50个年度关键词》报告,通过梳理50个关键词,全面展现了AI领域的最新进展、技术趋势和未来方向。这份报告不仅为AI从业者提供了宝贵的参考,也为普通读者打开了了解AI的窗口。本…

不再头痛!算法备案自评估报告要点分析

算法备案材料包含众多报告,其中最难的莫过于《算法安全自评估报告》。本人经手过几十份该材料,今天就结合个人经验总结下自评估报告的要点及一些容易踩的坑,希望可以帮助大家。有其它问题也可以参考这篇文章了解。 一、自评估报告常见问题 1、前后矛盾 报告内部的算法、风控…

C语言中标准输出的缓冲机制

什么是缓冲区 缓存区是内存空间的一部分,再内存中,内存空间会预留一定的存储空间,这些存储空间是用来缓冲输入和输出的数据,预留的这部分空间就叫做缓冲区。 其中缓冲区还会根据对应的是输入设备还是输出设备分为输入缓冲区和输出缓冲区。 为什么需要缓冲? 直接操作硬件(…

k8s回调函数-cnblog

回调函数 Kubernetes 为容器提供了生命周期回调。 回调使容器能够了解其管理生命周期中的事件,并在执行相应的生命周期回调时运行在处理程序中实现的代码。Kubernetes 支持 PostStart 和 PreStop 事件。 当一个容器启动后,Kubernetes 将立即发送 PostStart 事件;在容器被终结…

Transfomer 中的强制教学(Teacher Forcing)

在预测阶段, 我们希望输入 "天雷滚滚我好怕怕" 和 "[cls]" 能预测出下一个token: 劈 于是我们在训练阶段,我们的输入是 "天雷滚滚我好怕怕" 和 “[cls]劈得我浑身掉渣渣”, 由于我们希望"[cls]" 能预测出 “劈” 字。 我们在损失函…

jenkins安装后可用插件版本需要高版本的jenkins才能使用

首先我们直接用清华镜像源https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/,比如我们要找Jenkins2.429对应版本 emmmm,没有429,427凑合用吧 获取这个地址,放到updatesite 进服务器,找到default.json,替换掉它,然后重启jenkins。 cp default.json default.json.ba…

​党政机关数字化转型必备:10款信创认证项目管理工具深度测评

党政机关数字化转型是适应时代发展、提升治理效能的关键举措。在这一过程中,信创认证项目管理工具发挥着至关重要的作用。它们不仅能助力项目高效推进,还能保障信息安全与合规性。以下将对10款信创认证项目管理工具进行深度测评,为党政机关在数字化转型道路上的工具选择提供…

材料焊接工艺大全-芯晨微纳(河南) -专注于激光代加工

一、材料焊接中的“焊接力” 材料焊接,准确说应该为“材料互联”,是通过物理力、化学力、机械作用力等方式将原本相互隔离的材料连为一体的过程。 物理力中的四种基本力是万有引力、电磁力、强相互作用力和弱相互作用力。具体的,按性质(根据它们的物理性质来命名和分类)分…