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

C++ 学习 —— 04 - STL容器

目录

一、STL概述

二、STL容器

2.1 顺序容器

2.1.1 顺序容器简介

2.1.2 array

2.1.3 vector

2.1.4 deque

2.1.5 list

2.2 关联容器

2.2.1 关联容器简介

2.2.2 set

2.2.3 map

2.3 容器适配器

2.3.1 stack(栈)

2.3.2 queue(队列)


一、STL概述

C++ STL(Standard Template Library,标准模板库)是 C++ 标准库中用于管理和存储数据集合的一组模板类。STL 提供了常用的数据结构(如数组、链表、队列、栈、集合、映射等)和算法,极大地提高了 C++ 开发的效率和代码的通用性。

二、STL容器

2.1 顺序容器
2.1.1 顺序容器简介

2.1.2 array

  • array 可以理解为静态数组,不能动态扩容或缩减。
  • 内存连续,支持高效随机访问。
  • array 容器元数据(如大小、容量、指向实际数据的指针)存放在栈中,实际存储元素也存放在栈中。
#include <iostream>
#include <array>
#include <algorithm> // sortusing namespace std;int main() {// 1. 定义 arrayarray<int, 5> arr = { 1, 2, 3, 4, 5 };// 2. 访问元素cout << arr[0] << endl;    // 1cout << arr.at(1) << endl; // 2  at()会检查越界cout << arr.front() << endl; // 1  // front() 返回首个元素cout << arr.back() << endl;  // 5  // back() 返回最后元素// 3. size() 获取已存放元素个数cout << arr.size() << endl;  // 5// 4. 遍历for (int i = 0; i < arr.size(); i++) {  // 当然我们也可以用基于范围的 for 循环cout << arr[i] << " ";  // 1 2 3 4 5}cout << endl;// 5. fill() 将 array 所有元素填充为指定元素arr.fill(10);  // 10 10 10 10 10// 6. swap() 交换两个 array 中的元素array<int, 5> arr1 = { 10,20,30,40,50 };arr.swap(arr1);// 7. data() 获取 array 指针int* p = arr.data();for (int i = 0; i < arr.size(); i++) {cout << p[i] << " ";  // 10 20 30 40 50}cout << endl;for (int i = 0; i < arr.size(); i++) {cout << *(p + i) << " ";  // 10 20 30 40 50}cout << endl;// 8. 使用迭代器遍历 // begin() 返回容器第一个元素的迭代器(可以理解为指针)  end() 返回容器最后一个元素(下一个位置)的迭代器(可以理解为指针) it++:向容器后面移动for (auto it = arr.begin(); it != arr.end(); it++) { cout << *it << " ";  // 10 20 30 40 50}cout << endl;// 使用反向迭代器遍历 // rbegin() 返回容器最后第一元素的迭代器(可以理解为指针)  rend() 返回容器第一个元素(上一个位置)的迭代器(可以理解为指针) rit++:向容器前面移动for (auto rit = arr.rbegin(); rit != arr.rend(); rit++) {cout << *rit << " ";  // 50 40 30 20 10}cout << endl;// 9. sort排序array<int, 5> arr2 = { 10,50,20,6,5 };sort(arr2.begin(), arr2.end()); // 5 6 10 20 50// 10. reverse() 逆置reverse(arr2.begin(), arr2.end()); // 50 20 10 6 5return 0;
}
2.1.3 vector

  • vector 可以理解为动态数组的另一种实现方式,可以动态扩容和缩减。且对尾部的插入删除速度相对较快。
  • 内存连续,支持高效随机访问。
  • vector 容器元数据(如大小、容量、指向实际数据的指针)存放在栈中,实际存储元素存放在堆中。

注意:vector 在动态扩容时,并不是在原空间之后续接新空间,而是寻找更大的内存空间,将原数据拷贝到新空间中,然后释放原空间。

#include <iostream>
#include <vector>
#include <algorithm> // sort, reverseusing namespace std;int main() {// 1. 定义 vectorvector<int> v1;          // 空 vectorvector<int> v2(5);       // 0 0 0 0 0vector<int> v3(5, 10);   // 10 10 10 10 10vector<int> v4 = { 1,2,3,4,5 };  // 1 2 3 4 5vector<int> v5(v4);      // 1 2 3 4 5  (拷贝构造)// 2. 访问元素cout << v4[0] << endl;     // 1cout << v4.at(1) << endl;  // 2cout << v4.front() << endl; // 1cout << v4.back() << endl;  // 5// 3. size() 获取已存放元素个数  capacity() 获取已分配的空间容量cout << v4.size() << endl;  // 5cout << v4.capacity() << endl;  // 5v4.reserve(100); // // 预留空间cout << v4.capacity() << endl;  // 100// 4. 遍历for (int i = 0; i < v4.size(); i++) {cout << v4[i] << " ";  // 1 2 3 4 5 }cout << endl;// 5. 尾部插入元素  尾部删除元素v4.push_back(6); // 1 2 3 4 5 6v4.pop_back();   // 1 2 3 4 5// 6. 插入元素 删除元素v4.insert(v4.begin(), 0); // 在位置 0 处插入元素 0             0 1 2 3 4 5 v4.insert(v4.begin() + 2, 999);  // 在位置 2 处插入元素 999    0 1 999 2 3 4 5 v4.insert(v4.end(), 6); // 在末尾插入元素 6                    0 1 999 2 3 4 5 6v4.erase(v4.begin()); // 删除位置 0 处的元素                   1 999 2 3 4 5 6v4.erase(v4.begin(), v4.begin() + 2); // 删除范围[0,2)              2 3 4 5 6// 7. swap() 交换两个 vector 中的元素v4.swap(v5);// 8. data() 获取 vector 指针int* p = v4.data();for (int i = 0; i < v4.size(); i++) {cout << p[i] << " ";  // 1 2 3 4 5}cout << endl;for (int i = 0; i < v4.size(); i++) {cout << *(p + i) << " ";  // 1 2 3 4 5}cout << endl;// 9. 使用迭代器遍历 for (auto it = v4.begin(); it != v4.end(); it++) {cout << *it << " ";  // 1 2 3 4 5}cout << endl;// 使用反向迭代器遍历 for (auto rit = v4.rbegin(); rit != v4.rend(); rit++) {cout << *rit << " ";  // 5 4 3 2 1}cout << endl;// 9. sort排序sort(v4.begin(), v4.end()); // 1 2 3 4 5// 10. reverse() 逆置reverse(v4.begin(), v4.end()); // 5 4 3 2 1return 0;
}
2.1.4 deque

  • 相比于 vector,deque 对头部的插入删除速度相对较快。
  • 内存分块管理,支持随机访问。
  • deque 容器元数据(如大小、容量、指向实际数据的指针)存放在栈中,实际存储元素存放在堆中。
#include <iostream>
#include <deque>
#include <algorithm> // sort, reverseusing namespace std;int main() {// 1. 定义 dequedeque<int> d1;          // 空 dequedeque<int> d2(5);       // 0 0 0 0 0deque<int> d3(5, 10);   // 10 10 10 10 10deque<int> d4 = { 1,2,3,4,5 };  // 1 2 3 4 5deque<int> d5(d4);      // 1 2 3 4 5  (拷贝构造)// 2. 访问元素cout << d4[0] << endl;     // 1cout << d4.at(1) << endl;  // 2cout << d4.front() << endl; // 1cout << d4.back() << endl;  // 5// 3. size() 获取已存放元素个数   注意: deque 没有 capacity() 和 data() 方法, 因为其内存空间不是连续的cout << d4.size() << endl;  // 5// 4. 遍历for (int i = 0; i < d4.size(); i++) {cout << d4[i] << " ";  // 1 2 3 4 5 }cout << endl;// 5. 尾部插入元素  尾部删除元素d4.push_back(6); // 1 2 3 4 5 6d4.pop_back();   // 1 2 3 4 5// 6. 头部插入元素 头部删除元素d4.push_front(0); // 0 1 2 3 4 5d4.pop_front();   // 1 2 3 4 5// 7. 插入元素 删除元素d4.insert(d4.begin(), 0); // 在位置 0 处插入元素 0             0 1 2 3 4 5 d4.insert(d4.begin() + 2, 999);  // 在位置 2 处插入元素 999    0 1 999 2 3 4 5 d4.insert(d4.end(), 6); // 在末尾插入元素 6                    0 1 999 2 3 4 5 6d4.erase(d4.begin()); // 删除位置 0 处的元素                   1 999 2 3 4 5 6d4.erase(d4.begin(), d4.begin() + 2); // 删除范围[0,2)              2 3 4 5 6// 8. swap() 交换两个 deque 中的元素d4.swap(d5);// 9. 使用迭代器遍历 for (auto it = d4.begin(); it != d4.end(); it++) {cout << *it << " ";  // 1 2 3 4 5}cout << endl;// 使用反向迭代器遍历 for (auto rit = d4.rbegin(); rit != d4.rend(); rit++) {cout << *rit << " ";  // 5 4 3 2 1}cout << endl;// 9. sort排序sort(d4.begin(), d4.end()); // 1 2 3 4 5// 10. reverse() 逆置reverse(d4.begin(), d4.end()); // 5 4 3 2 1return 0;
}
2.1.5 list

  • 插入/删除效率高(任何位置),但随机访问慢。
  • 内存分散,占用空间较大(需额外存储前后指针)。
  • list 容器元数据(如大小、容量、指向实际数据的指针)存放在栈中,实际存储元素存放在堆中。
#include <iostream>
#include <list>
#include <algorithm> // sort, reverseusing namespace std;int main() {// 1. 定义 listlist<int> l1;            // 空 listlist<int> l2(5);         // 5 个元素,默认值 0list<int> l3(5, 10);     // 5 个元素,值为 10list<int> l4 = { 1, 2, 3, 4, 5 }; // 列表初始化list<int> l5(l4);        // 拷贝构造// 2. 访问元素cout << l4.front() << endl; // 1cout << l4.back() << endl;  // 5// 注意:list 不支持 operator[] 或 at(),因为它不是随机访问容器// 3. size() cout << l4.size() << endl;   // 5// 4. 迭代器遍历for (auto it = l4.begin(); it != l4.end(); ++it) {cout << *it << " ";  // 1 2 3 4 5}cout << endl;// 5. 尾部插入/删除l4.push_back(6);  // 1 2 3 4 5 6l4.pop_back();    // 1 2 3 4 5// 6. 头部插入/删除l4.push_front(0); // 0 1 2 3 4 5l4.pop_front();   // 1 2 3 4 5// 7. 插入元素 删除元素auto it = l4.begin();advance(it, 2);  // 将迭代器移动到第 2 个位置l4.insert(it, 999); // 1 2 999 3 4 5it = l4.begin();advance(it, 2);l4.erase(it); // 1 2 3 4 5// 8. 删除所有满足条件的元素l4.remove(3); // 1 2 4 5// 9. swap()l4.swap(l5);  // 1 2 3 4 5// 10. sort排序l4.sort(); // 1 2 3 4 5// 11. reverse 反转l4.reverse(); // 5 4 3 2 1// 12. unique 删除相邻重复元素list<int> l6 = { 1,1,2,2,2,3,3,4 };l6.unique(); // 1 2 3 4return 0;
}

2.2 关联容器
2.2.1 关联容器简介

关联式容器以平衡二叉搜索树(标准实现通常为红黑树) 为底层结构,元素按“键”排序,查找、插入、删除均为 O(log n)。

2.2.2 set
  • 所有元素在插入时自动被排序。
  • 不允许有重复元素。
#include <iostream>
#include <set>
using namespace std;int main() {// 1. 定义 setset<int> s1;                  // 空 setset<int> s2 = { 5, 3, 1, 4, 2 }; // 1 2 3 4 5set<int> s3(s2);              // 1 2 3 4 5// 2. size()cout << s2.size() << endl;  // 5// 3. 迭代器遍历 for (auto it = s2.begin(); it != s2.end(); ++it) {cout << *it << " ";  // 1 2 3 4 5}cout << endl;// 4. 插入元素 删除元素s2.insert(10); // 1 2 3 4 5 10s2.erase(5); // 1 2 3 4 10// 5. 查找元素 // find()   如果找到则返回该元素的迭代器,如果没有找到则返回 end()// count()  如果找到则返回 1,如果没有找到则返回 0auto it = s2.find(3); if (it != s2.end()) cout << "找到了" << endl;cout << s2.count(3) << endl; // 1 // 6. swap()set<int> s4 = { 1,2,3 };s2.swap(s4);  // 1 2 3return 0;
}
2.2.3 map
  • map 中所有元素都是 pair。pair 中第一个元素为 key(键值),起到索引作用,第二个元素为 value(实值)
  • 所有元素在插入时自动被排序。
  • 不允许有重复元素(key)。
#include <iostream>
#include <map>
#include <string>
using namespace std;int main() {// 1️. 定义 mapmap<int, string> m1; // 空 mapmap<int, string> m2 = { {1, "apple"}, {2, "banana"}, {3, "cherry"} };// 2. 迭代器遍历for (auto it = m2.begin(); it != m2.end(); ++it)cout << it->first << " : " << it->second << endl;// 3. 插入元素m1.insert({ 1, "cat" });m1.insert(make_pair(2, "dog"));m1[3] = "bird";   // 若存在则修改,不存在则创建m1[4] = "fish";m1.emplace(5, "tiger"); // 原地构造// 4. 删除元素m1.erase(1);                // 按 key 删除m1.erase(m1.begin());       // 按迭代器删除// 5. 查找auto it = m1.find(3);if (it != m1.end()) cout << "找到了" << endl;cout << m1.count(3) << endl; // 1// 6. swap()m1.swap(m2);return 0;
}
2.3 容器适配器
2.3.1 stack(栈)

后进先出,底层一般用 deque 实现。

2.3.2 queue(队列)

先进先出,底层一般用 deque 实现。

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

相关文章:

  • 什么是端口管理?网络安全的关键环节
  • 竞品网站分析温州企业网站制作
  • Apache Paimon 写入流程
  • 如何设计一个秒杀系统(下)
  • 投资网站策划晋江市建设局网站
  • 博客阅读:chatgpt 2025 GPT-5 Jailbreak with Echo Chamber and Storytelling
  • 经典模板网站建设wordpress函数讲解
  • HTTP协议与WebSocket完整技术指南
  • 时序数据库核心技术解析-以InfluxDB/TSDB为例
  • 各大网站收录入口ASP.NET与网站开发编程实战
  • 招聘网站建设与开发要求typecho转wordpress
  • 专为严苛环境而生:高防护等级工业防水平板WPPC-H1520T(P)
  • 网站建设销售培训好网站的标准
  • 当多进程遇上异步:一次 Celery 与 Async SQLAlchemy 的边界冲突
  • 【Tailwind,DaisyUI】如何让 button 文字左对齐?
  • 【IC】NoC设计入门 -- 传统总线Bus
  • CoDeGAN:用对比学习重新定义GAN中的表示解耦
  • hive中数据的来源
  • 企业营销型网站的内容路由器 搭建wordpress
  • 2.4、恶意软件猎手:基于深度学习的二进制文件判别
  • 力扣hot100---42.接雨水(java版)
  • 长春公司建站模板三把火科技网站设计
  • Nine.fun:连接现实娱乐与Web3经济的全新生态
  • 【职业方向】2026小目标,从web开发转型web3开发【一】
  • 用 Playwright + 容器化做分布式浏览器栈:调度、会话管理与资源回收
  • 148.PCIE参考时钟无法绑定
  • 国际网站如何做seo电脑网站模版
  • LeetCode 414 - 第三大的数
  • HAProxy 配置实操 (OpenEuler为例)
  • 前端(Vue框架)实现主题切换