学懂C++(四十五 ):深入详解C++ STL 容器:从基础到进阶

news/2024/9/18 3:54:40/ 标签: c++, 开发语言, STL, 容器

      

目录

1. 向量(Vector)

概念

特点

核心点

实现

适用场景

代码解析

2. 双端队列(Deque)

概念

特点

核心点

实现

适用场景

代码解析

3. 列表(List)

概念

特点

核心点

实现

适用场景

代码解析

4. 集合(Set)

概念

特点

核心点

实现

适用场景

代码解析

5. 映射(Map)

概念

特点

核心点

实现

适用场景

代码解析

6. 无序集合(Unordered Set)

概念

特点

核心点

实现

适用场景

代码解析

7. 无序映射(Unordered Map)

概念

特点

核心点

实现

适用场景

代码解析

8. 栈(Stack)

概念

特点

核心点

实现

适用场景

代码解析

9. 队列(Queue)

概念

特点

核心点

实现

适用场景

代码解析

10. 优先队列(Priority Queue)

概念

特点

核心点

实现

适用场景

代码解析

总结


          C++ 标准模板库(STL)是一个非常强大的工具集,提供了一组通用的类和函数,用于数据结构和算法的实现。STL 的核心组件包括容器(Containers)、迭代器(Iterators)和算法(Algorithms)。本文将深入探讨 STL 容器,全面讲解其概念、特点、核心点、实现、适用场景,并通过经典示例代码和详细解析,帮助开发者更好地理解和应用 STL 容器

1. 向量(Vector)

概念

std::vector 是一个模板类,表示一个可以动态调整大小的数组。它可以高效地在末尾添加和删除元素,提供随机访问功能。

特点

  • 动态大小:可以自动调整大小。
  • 随机访问:支持常数时间的随机访问。
  • 连续内存:存储在连续的内存块中,兼容C风格数组。

核心点

  • 内存管理:使用动态数组管理内存,自动处理内存分配和释放。
  • 扩展策略:当容量不足时,通常会按一定比例(通常是2倍)扩展容量。

实现

#include <iostream>
#include <vector>void vectorExample()
{std::vector<int> vec;// 添加元素vec.push_back(1);vec.push_back(2);vec.push_back(3);// 随机访问std::cout << "Element at index 1: " << vec[1] << std::endl;// 迭代访问for(const auto& elem : vec){std::cout << elem << " ";}std::cout << std::endl;
}

适用场景

  • 需要动态调整大小的数组。
  • 需要高效随机访问的场景。

代码解析

  1. push_back:在向量末尾添加元素。
  2. 随机访问:使用下标操作符[]访问元素。
  3. 迭代访问:使用范围基于(range-based)for循环迭代访问元素。

2. 双端队列(Deque)

概念

std::deque 是一个双端队列,支持在两端高效地添加和删除元素。

特点

  • 双端操作:在两端添加和删除元素都很高效。
  • 随机访问:支持常数时间的随机访问。
  • 分段存储:内部实现为一组连续的内存块,提高内存管理效率。

核心点

  • 双端操作push_front 和 push_back 方法用于在两端添加元素。
  • 内存管理:使用分段存储来优化内存管理。

实现

#include <iostream>
#include <deque>void dequeExample()
{std::deque<int> deq;// 在两端添加元素deq.push_back(1);deq.push_back(2);deq.push_front(0);// 随机访问std::cout << "Element at index 1: " << deq[1] << std::endl;// 迭代访问for(const auto& elem : deq){std::cout << elem << " ";}std::cout << std::endl;
}

适用场景

  • 需要在两端频繁添加和删除元素的场景。
  • 需要高效随机访问的场景。

代码解析

  1. push_front:在队列前端添加元素。
  2. push_back:在队列末尾添加元素。
  3. 随机访问:使用下标操作符[]访问元素。

3. 列表(List)

概念

std::list 是一个双向链表,支持在任意位置高效地插入和删除元素。

特点

  • 双向链表:每个元素包含指向前后元素的指针。
  • 高效插入和删除:在链表的任意位置插入和删除元素都很高效。
  • 顺序访问:不支持随机访问,只能顺序访问。

核心点

  • 链表结构:使用双向链表实现,保证高效的插入和删除操作。
  • 迭代器:提供双向迭代器,支持前向和后向遍历。

实现

#include <iostream>
#include <list>void listExample()
{std::list<int> lst;// 添加元素lst.push_back(1);lst.push_back(2);lst.push_front(0);// 迭代访问for(const auto& elem : lst){std::cout << elem << " ";}std::cout << std::endl;// 插入和删除元素auto it = lst.begin();++it;lst.insert(it, 10);lst.erase(it);
}

适用场景

  • 需要在任意位置频繁插入和删除元素的场景。
  • 需要顺序访问的场景。

代码解析

  1. push_front:在链表前端添加元素。
  2. push_back:在链表末尾添加元素。
  3. inserterase:在链表的任意位置插入和删除元素。
  4. 迭代访问:使用范围基于(range-based)for循环迭代访问元素。

4. 集合(Set)

概念

std::set 是一个有序集合,存储唯一的元素并自动对元素进行排序。

特点

  • 有序:元素自动排序。
  • 唯一性:集合中的元素是唯一的。
  • 高效查找:支持对元素的高效查找。

核心点

  • 有序集合:使用红黑树实现,保证元素的有序性和查找效率。
  • 唯一性:自动去重,保证元素的唯一性。

实现

#include <iostream>
#include <set>void setExample()
{std::set<int> s;// 添加元素s.insert(3);s.insert(1);s.insert(2);s.insert(2); // 重复元素插入无效// 迭代访问for(const auto& elem : s){std::cout << elem << " ";}std::cout << std::endl;// 查找元素auto it = s.find(2);if(it != s.end()){std::cout << "Element found: " << *it << std::endl;}else{std::cout << "Element not found" << std::endl;}
}

适用场景

  • 需要存储唯一且有序的元素集合。
  • 需要高效查找元素的场景。

代码解析

  1. insert:在集合中添加元素,自动去重。
  2. find:在集合中查找元素。
  3. 迭代访问:使用范围基于(range-based)for循环迭代访问元素。

5. 映射(Map)

概念

std::map 是一个有序映射,存储键值对,并根据键对元素进行排序。

特点

  • 有序:键值对自动排序。
  • 键唯一:每个键在映射中是唯一的。
  • 高效查找:支持对键的高效查找。

核心点

  • 有序映射:使用红黑树实现,保证键值对的有序性和查找效率。
  • 唯一键:自动去重,保证键的唯一性。

实现

#include <iostream>
#include <map>void mapExample()
{std::map<int, std::string> m;// 添加键值对m[1] = "one";m[2] = "two";m[3] = "three";// 迭代访问for(const auto& pair : m){std::cout << pair.first << ": " << pair.second << std::endl;}// 查找键值对auto it = m.find(2);if(it != m.end()){std::cout << "Element found: " << it->first << ": " << it->second << std::endl;}else{std::cout << "Element not found" << std::endl;}
}

适用场景

  • 需要存储键值对并根据键进行排序的场景。
  • 需要高效查找键的场景。

代码解析

  1. operator[]:在映射中添加或访问键值对。
  2. find:在映射中查找键。
  3. 迭代访问:使用范围基于(range-based)for循环迭代访问键值对。

6. 无序集合(Unordered Set)

概念

std::unordered_set 是一个无序集合,存储唯一的元素并使用哈希表进行管理。

特点

  • 无序:元素没有特定顺序。
  • 唯一性:集合中的元素是唯一的。
  • 高效查找:使用哈希表实现,对元素进行高效查找。

核心点

  • 无序集合:使用哈希表实现,保证元素的唯一性和查找效率。
  • 唯一性:自动去重,保证元素的唯一性。

实现

#include <iostream>
#include <unordered_set>void unorderedSetExample()
{std::unordered_set<int> us;// 添加元素us.insert(3);us.insert(1);us.insert(2);us.insert(2); // 重复元素插入无效// 迭代访问for(const auto& elem : us){std::cout << elem << " ";}std::cout << std::endl;// 查找元素auto it = us.find(2);if(it != us.end()){std::cout << "Element found: " << *it << std::endl;}else{std::cout << "Element not found" << std::endl;}
}

适用场景

  • 需要存储唯一且无序的元素集合。
  • 需要高效查找元素的场景。

代码解析

  1. insert:在集合中添加元素,自动去重。
  2. find:在集合中查找元素。
  3. 迭代访问:使用范围基于(range-based)for循环迭代访问元素。

7. 无序映射(Unordered Map)

概念

std::unordered_map 是一个无序映射,存储键值对,并使用哈希表进行管理。

特点

  • 无序:键值对没有特定顺序。
  • 键唯一:每个键在映射中是唯一的。
  • 高效查找:使用哈希表实现,对键进行高效查找。

核心点

  • 无序映射:使用哈希表实现,保证键的唯一性和查找效率。
  • 唯一键:自动去重,保证键的唯一性。

实现

#include <iostream>
#include <unordered_map>void unorderedMapExample()
{std::unordered_map<int, std::string> um;// 添加键值对um[1] = "one";um[2] = "two";um[3] = "three";// 迭代访问for(const auto& pair : um){std::cout << pair.first << ": " << pair.second << std::endl;}// 查找键值对auto it = um.find(2);if(it != um.end()){std::cout << "Element found: " << it->first << ": " << it->second << std::endl;}else{std::cout << "Element not found" << std::endl;}
}

适用场景

  • 需要存储键值对并使用哈希表进行管理的场景。
  • 需要高效查找键的场景。

代码解析

  1. operator[]:在映射中添加或访问键值对。
  2. find:在映射中查找键。
  3. 迭代访问:使用范围基于(range-based)for循环迭代访问键值对。

8. 栈(Stack)

概念

std::stack 是一个适配器容器,提供后进先出(LIFO)的数据结构。

特点

  • LIFO:后进先出顺序。
  • 适配器容器:通常基于 std::deque 或 std::vector 实现。

核心点

  • LIFO 数据结构:提供 pushpop 和 top 方法。
  • 适配器模式:基于其他容器实现。

实现

#include <iostream>
#include <stack>void stackExample()
{std::stack<int> st;// 添加元素st.push(1);st.push(2);st.push(3);// 访问栈顶元素std::cout << "Top element: " << st.top() << std::endl;// 移除栈顶元素st.pop();std::cout << "Top element after pop: " << st.top() << std::endl;
}

适用场景

  • 需要后进先出(LIFO)数据结构的场景,如递归调用、表达式求值等。

代码解析

  1. push:在栈顶添加元素。
  2. pop:移除栈顶元素。
  3. top:访问栈顶元素。

9. 队列(Queue)

概念

std::queue 是一个适配器容器,提供先进先出(FIFO)的数据结构。

特点

  • FIFO:先进先出顺序。
  • 适配器容器:通常基于 std::deque 实现。

核心点

  • FIFO 数据结构:提供 pushpop 和 front 方法。
  • 适配器模式:基于其他容器实现。

实现

#include <iostream>
#include <queue>void queueExample()
{std::queue<int> q;// 添加元素q.push(1);q.push(2);q.push(3);// 访问队首元素std::cout << "Front element: " << q.front() << std::endl;// 移除队首元素q.pop();std::cout << "Front element after pop: " << q.front() << std::endl;
}

适用场景

  • 需要先进先出(FIFO)数据结构的场景,如任务调度、消息队列等。

代码解析

  1. push:在队列末尾添加元素。
  2. pop:移除队首元素。
  3. front:访问队首元素。

10. 优先队列(Priority Queue)

概念

std::priority_queue 是一个适配器容器,提供按优先级排序的队列。

特点

  • 优先级排序:元素按照优先级排序。
  • 适配器容器:通常基于 std::vector 和堆算法实现。

核心点

  • 优先级数据结构:提供 pushpop 和 top 方法。
  • 适配器模式:基于其他容器和算法实现。

实现

#include <iostream>
#include <queue>
#include <vector>void priorityQueueExample()
{std::priority_queue<int, std::vector<int>> pq;// 添加元素pq.push(1);pq.push(3);pq.push(2);// 访问最高优先级元素std::cout << "Top element: " << pq.top() << std::endl;// 移除最高优先级元素pq.pop();std::cout << "Top element after pop: " << pq.top() << std::endl;
}

适用场景

  • 需要按优先级处理元素的场景,如任务调度、A*算法等。

代码解析

  1. push:在优先队列中添加元素。
  2. pop:移除最高优先级元素。
  3. top:访问最高优先级元素。

总结

        本文详细介绍了 C++ STL 各种常用容器,包括向量(Vector)、双端队列(Deque)、列表(List)、集合(Set)、映射(Map)、无序集合(Unordered Set)、无序映射(Unordered Map)、栈(Stack)、队列(Queue)和优先队列(Priority Queue)。每种容器的概念、特点、核心点、实现方法、适用场景以及经典示例代码和详细解析都进行了深入讲解。

        通过对这些容器的学习和应用,开发者可以更好地应对软件开发中的复杂问题,提高代码的质量和开发效率,充分发挥


http://www.ppmy.cn/news/1516870.html

相关文章

大模型备案重难点最详细说明【评估测试题+附件】

2024年3月1日&#xff0c;我国通过了《生成式人工智能服务安全基本要求》&#xff08;以下简称《AIGC安全要求》&#xff09;&#xff0c;这是目前我国第一部有关AIGC服务安全性方面的技术性指导文件&#xff0c;对语料安全、模型安全、安全措施、词库/题库要求、安全评估等方面…

设计模式(二):工厂模式

一&#xff0c;什么是工厂模式 工厂模式&#xff08;Factory Pattern&#xff09; 是一种创建型设计模式&#xff0c;它定义了一个用于创建对象的接口&#xff0c;而不需要显式地指定对象所属的具体类。换句话说&#xff0c;工厂模式将对象的实例化过程延迟到子类或其他工厂方…

【论文阅读】NGD-SLAM: Towards Real-Time SLAM for Dynamic Environments without GPU

arxiv上一篇很新的视觉SLAM论文&#xff0c;能够在不使用GPU的情况下进行语义分割的辅助运算。 一、跟踪流程 作为一个语义结合的视觉SLAM&#xff0c;其基本的思路和以前看过的DynaSLAM基本类似&#xff0c;都是依赖语义分割模型对场景中动态的特征点进行剔除&#xff0c;这…

【jvm】栈是否存在垃圾回收

目录 一、栈的特点1.1 栈内存分配1.2 栈的生命周期1.3 垃圾回收不直接涉及 二、堆与栈的区别三、总结 一、栈的特点 1.1 栈内存分配 1.栈内存分配是自动的&#xff0c;不需要程序员手动分配和释放。 2.每当一个方法被调用时&#xff0c;JVM就会在这个线程的栈上创建一个新的栈…

C++ | Leetcode C++题解之第355题设计推特

题目&#xff1a; 题解&#xff1a; class Twitter {struct Node {// 哈希表存储关注人的 Idunordered_set<int> followee;// 用链表存储 tweetIdlist<int> tweet;};// getNewsFeed 检索的推文的上限以及 tweetId 的时间戳int recentMax, time;// tweetId 对应发送…

使用GDIView工具排查GDI对象泄漏案例的若干细节总结

目录 1、查看任务管理器,发现程序中有明显的GDI对象泄漏 2、使用GDIView工具查看发生泄漏的是哪一种GDI对象 3、尝试找到复现问题的方法,缩小排查范围,逐步地找到GDI对象的泄漏点 4、本案例中的相关细节点的思考与总结(有价值的细节点) 4.1、UI界面无法显示的原因分析…

TypeScript 面试题汇总

引言 TypeScript 是一种由微软开发的开源、跨平台的编程语言&#xff0c;它是 JavaScript 的超集&#xff0c;为 JavaScript 添加了静态类型系统和其他高级功能。随着 TypeScript 在前端开发领域的广泛应用&#xff0c;掌握 TypeScript 已经成为很多开发者必备的技能之一。本文…

Clickhouse集群化(六)clickhosue-operator学习

1. Custom Resource元素 apiVersion: "clickhouse.altinity.com/v1" kind: "ClickHouseInstallation" metadata:name: "clickhouse-installation-test" 这是clickhouse operator自定义的资源ClickHouseInstallation 1.1. .spec.defaults spe…

35次8.23(docker02)

#搜索拉取镜像 docker search centos docker pull centos #创建启动容器 docker run -it --namea0 centod:latest echo "abc" #如果容器中没有正在执行的指令&#xff0c;就会exit docker run -it --namea0 cenyos:latest /bin/bash #查看docker进程 docker ps #发现…

SQL,解析 json

Google BigQuery数据库的data表存储了若干多层的Json串&#xff0c;其中一条形如&#xff1a; [{"active":true,"key":"key1","values":[{"active":true,"value":"value1"}]},{"active":tru…

go 系列实现websocket

一、简介 websocket是个二进制协议&#xff0c;需要先通过Http协议进行握手&#xff0c;从而协商完成从Http协议向websocket协议的转换。一旦握手结束&#xff0c;当前的TCP连接后续将采用二进制websocket协议进行双向双工交互&#xff0c;自此与Http协议无关。 二、websocket…

uni-app 手记集。

1、uni-app 是一个使用 Vue.js 开发的前端应用的框架&#xff0c;所以不会Vue.js的小伙伴可以先去看看Vue.js的基础教学。 2、.vue文件结构 <template><div class"container"></div> </template><script type"text/ecmascript-6&q…

未来城市的科技展望

未来城市&#xff0c;‌将是科技与人文深度融合的产物&#xff0c;‌展现出一个全方位智能化、‌绿色生态且可持续发展的全新面貌。‌随着物联网、‌人工智能等技术的飞速发展&#xff0c;‌未来城市的轮廓逐渐清晰&#xff0c;‌它将为我们带来前所未有的生活体验。‌ 在未来…

吴光明为鱼跃集团指明方向 以用户为核心构建发展战略

鱼跃集团创始人吴光明&#xff0c;始终秉持着以用户需求为核心的发展理念&#xff0c;引领企业构建技术与产品的双轮驱动体系。 在他的远见卓识下&#xff0c;鱼跃集团明确了以呼吸治疗解决方案、糖尿病管理及POCT、感染控制为三大核心支柱的战略布局&#xff0c;同时保持家用…

SAP怎么查找系统全部的增强点呢?

1.在已有的BADI查找程序里面有点手无足措的样子&#xff0c;不知道该如何去找增强&#xff01; 2.这个时候刚刚接触系统还不熟悉&#xff0c;系统里面存在了什么增强&#xff0c;这个时候咋办捏&#xff1f;SE38 -SNIF 此时全部的增强点都在这里面啦&#xff01;&#xff01;&…

bitsandbytes使用错误:CUDA Setup failed despite GPU being available

参考:https://huggingface.co/docs/bitsandbytes/main/en/installation 报错信息 ======================

一文了解机器学习顶会ICML 2024的研究热点

对人工智能研究领域前沿方向的跟踪是提高科研能力和制定科研战略的关键。本文通过图文并茂的方式介绍了ICML 2024的研究热点&#xff0c;帮助读者了解和跟踪机器学习和人工智能的前沿研究方向。本推文的作者是许东舟&#xff0c;审校为邱雪和黄星宇。 1 会议介绍 ICML&#x…

java在实际开发中反常识bug

目录 1.背景 2.案例 1.包装类型拆箱导致空指针异常 2.switch传入null,导致空指针异常 3.Arrays.asList添加异常 4.转BigDecimal类型时精度丢失 5.除以0不一定抛异常 6.Steam filter后集合修改,会修改原数据 3.完美&评论 1.背景 这篇博客,将列举本人在实际开发中看…

复现ssrf漏洞

目录 一、pikachu靶场 1、靶场环境&#xff1a; 使用docker拉取&#xff1a; docker run -d -p 8765:80 8023/pikachu-expect:latest 2、使用dict 3、使用file读取文件 二、redis未授权访问 1、源码 2、使用bp探测端口 3、继续使用bp探测172.18.0.2的端口 4、使用go…

如何使用ssm实现基于VUE的新闻类网站+vue修改完的

TOC ssm272基于VUE的新闻类网站vue修改完的 系统概述 进过系统的分析后&#xff0c;就开始记性系统的设计&#xff0c;系统设计包含总体设计和详细设计。总体设计只是一个大体的设计&#xff0c;经过了总体设计&#xff0c;我们能够划分出系统的一些东西&#xff0c;例如文件…