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

标准模板库(STL)中的一个容器 都有什么

  1. 序列容器(Sequential Containers)
    • vector
      • 特点
        • 可以简单理解为一个动态数组,它在内存中是连续存储的。这使得它支持快速随机访问,通过索引访问元素的时间复杂度为常数时间 。例如,对于一个vector<int>类型的容器v,可以使用v[3]来快速访问第 4 个元素(索引从 0 开始)。
        • 但是,在中间或头部插入 / 删除元素可能比较耗时,因为需要移动插入 / 删除位置之后的所有元素。插入操作在尾部比较高效,平均时间复杂度为常数时间(如果不考虑可能的内存重新分配情况)。
      • 适用场景
        • 适用于需要频繁访问元素,且元素数量变化不太频繁(尤其是在中间位置的插入和删除操作不多)的场景。例如,存储一个图形程序中的顶点坐标列表,这些坐标在初始化后通常只是读取用于绘制,很少在中间插入或删除新的坐标。
    • list
      • 特点
        • 如前面所说,它是一个双向链表。每个节点包含数据和指向前一个节点、后一个节点的指针。这使得它在任何位置插入和删除元素都比较高效,时间复杂度为 ,因为只需要修改节点之间的指针关系。
        • 但是,随机访问元素比较慢,需要从链表头(或尾)开始遍历,访问第  个元素的时间复杂度为 。
      • 适用场景
        • 适合需要频繁插入和删除元素,而对随机访问要求不高的场景。例如,在一个任务调度系统中,任务可能会频繁地添加和移除,用list来存储任务列表可以高效地处理这些操作。
    • deque(双端队列)
      • 特点
        • 是一种双端队列容器,它的名字是 “double - ended queue” 的缩写。它允许在两端(头部和尾部)快速插入和删除元素,时间复杂度为 。
        • 它在内存中的存储方式与vector不同,不是连续的单一内存块,而是由多个固定大小的块组成,这使得它在两端的操作性能较好,但随机访问性能不如vector,不过仍然比list好一些,访问元素的时间复杂度为 (在最坏情况下,是元素个数)。
      • 适用场景
        • 适用于需要在两端高效操作的场景,如实现一个简单的滑动窗口算法,在窗口的两端添加和移除数据点。
    • forward_list(单向链表)
      • 特点
        • 这是一个单向链表容器,每个节点只包含一个指向下一个节点的指针。相比list,它的内存占用可能会稍小一些,因为少了一个指针。它在头部插入和删除元素非常快,时间复杂度为 ,但在其他位置插入和删除操作相对复杂,因为需要遍历找到插入位置的前一个节点。
        • 由于是单向链表,它不支持反向遍历,随机访问性能也很差,访问第  个元素的时间复杂度为 。
      • 适用场景
        • 适用于只需要单向遍历,且主要在头部进行插入和删除操作的场景。例如,实现一个简单的事件队列,事件按照产生的顺序添加到队列头部,然后从头部依次处理。
  2. 关联容器(Associative Containers)
    • map
      • 特点
        • map是一个键 - 值对容器,它按照键(key)进行排序(默认是升序)。键是唯一的,通过键可以快速查找对应的的值,查找、插入和删除操作的时间复杂度在平均情况下为 (是元素个数)。
        • 例如,对于一个map<int, string>类型的容器m,可以通过m[1]来获取键为 1 对应的字符串值(如果键不存在,会插入一个默认值并返回这个默认值,这可能会导致意外的插入操作,所以有时候需要先检查键是否存在)。
      • 适用场景
        • 适用于需要根据键来快速查找、插入和删除值的场景。比如,存储一个学生的学号(键)和姓名(值)的对应关系,通过学号快速查找学生姓名。
    • multimap
      • 特点
        • map类似,也是键 - 值对容器,但是键可以不唯一,即可以有多个键相同的键 - 值对。查找、插入和删除操作的时间复杂度在平均情况下也为 。
        • 当查找一个键时,会返回所有具有该键的键 - 值对范围。例如,在一个存储单词(键)和出现位置(值)的multimap中,查找一个单词时,可以得到这个单词在文本中所有出现的位置。
      • 适用场景
        • 适用于需要存储多个具有相同键的键 - 值对的场景,如统计一个文本中每个单词出现的次数和位置。
    • set
      • 特点
        • set是一个只存储键的容器,键是唯一的,并且会按照一定顺序(默认升序)自动排序。它的主要操作包括插入、删除和查找,时间复杂度在平均情况下为 。
        • 例如,对于一个set<int>类型的容器s,可以使用count函数检查一个整数是否在集合中,或者使用insert函数插入一个新元素。
      • 适用场景
        • 适用于需要存储一组唯一元素,并经常进行查找、插入和删除操作,同时对元素的顺序有要求的场景。比如,存储一个游戏中的玩家等级列表,每个等级只出现一次,并且可以方便地检查某个等级是否存在。
    • multiset
      • 特点
        • set类似,但允许存储相同的元素,即元素可以不唯一。它的操作时间复杂度在平均情况下也为 。
        • 例如,在一个存储学生成绩的multiset中,可以有多个学生得到相同的成绩。
      • 适用场景
        • 适用于需要存储可能有重复元素的集合,并且需要进行排序和快速查找操作的场景。如统计一个班级学生的考试成绩分布,相同的成绩可能会有多个学生。
  3. 容器适配器(Container Adapters)
    • stack(栈)
      • 特点
        • 栈是一种后进先出(LIFO)的数据结构,它可以基于vectorlistdeque来实现(默认通常是deque)。主要操作有push(入栈)、pop(出栈)和top(查看栈顶元素),pushpop操作的时间复杂度为 。
        • 例如,在一个表达式求值的程序中,可以使用栈来存储操作数和运算符,按照运算顺序进行处理。
      • 适用场景
        • 适用于需要实现后进先出操作的场景,如函数调用栈、表达式求值等。
    • queue(队列)
      • 特点
        • 队列是一种先进先出(FIFO)的数据结构,同样可以基于vectorlistdeque实现(默认通常是deque)。主要操作包括enqueue(入队)、dequeue(出队)和front(查看队首元素),enqueuedequeue操作的时间复杂度为 。
        • 例如,在一个任务调度系统中,任务按照到达的顺序排队等待执行,可以用队列来存储这些任务。
      • 适用场景
        • 适用于需要实现先进先出操作的场景,如任务排队、消息队列等。
    • priority_queue(优先队列)
      • 特点
        • 优先队列是一种特殊的队列,它的元素按照一定的优先级顺序出队,通常是基于堆(heap)实现的。默认情况下,最大元素(对于std::less比较器)或者最小元素(对于std::greater比较器)先出队,插入和删除操作的时间复杂度在平均情况下为 。
        • 例如,在一个操作系统的进程调度中,可以根据进程的优先级将进程放入优先队列,优先级高的进程先执行。
      • 适用场景
        • 适用于需要按照优先级处理元素的场景,如事件驱动系统中的事件处理,根据事件的紧急程度安排处理顺序。

http://www.kler.cn/a/447389.html

相关文章:

  • ARM学习(38)多进程多线程之间的通信方式
  • 工业摄像机基于电荷耦合器件的相机
  • 三格电子——新品IE103转ModbusTCP网关
  • C++ OCR银行卡文字识别
  • 【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题
  • vue-flow流程图组件
  • 基于SpringBoot的“旅游管理系统”的设计与实现(源码+数据库+文档+PPT)
  • 模型数据算法概论
  • 【Elasticsearch04】企业级日志分析系统ELK之Elasticsearch 插件
  • 方格分割(蓝桥杯2017年试题D)
  • 台球助教系统开发之助教预约功能模块需求分析(第十三章)
  • 【Python】利用函数模拟创建【栈】的数据结构操作
  • MFC/C++学习系列之简单记录6
  • Kubeadm+Containerd部署k8s(v1.28.2)集群(非高可用版)
  • Pytorch | 利用NI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
  • go-zero负载均衡实现原理
  • 重拾设计模式--模板方法模式
  • 书生·浦语大模型全链路开源体系-第6关 OpenCompass 评测
  • 苹果手机怎么清理空间:拯救你的拥挤手机
  • MyBatis主键自增回填功能源码分析