c++序列容器、关联容器、非序列关联容器简单介绍

c++ 关联容器用法详解(set与map) 三、关联容器 关联容器与序列容器有着根本性的不同,序列容器的元素是按照在容器中的位置来顺序保存和访问的,而关联容器的元素是按关键元素来保存和访问的。关联容器支持高效的关键字查找与访问。两个主要的关联容器类型是map与set。 1.set 1.1 简介:set里面每个元素只存有一个key,它支持高效的关键字查询操作。set对应数学中的“集合”。 1.2 特点: 储存同一类型的数据元素... 阅读详情
C++标准库提供了多种容器,主要分为序列容器、关联容器和无序关联容器。

序列容器:包括array, vector, deque, list, forward_list等,按线性顺序存储元素。

关联容器:包括set, map, multiset, multimap等,通常使用红黑树实现,元素按键排序。

无序关联容器:包括unordered_set, unordered_map, unordered_multiset, unordered_multimap等,使用哈希表实现,元素无序。

下面我们分别介绍这些容器,并对比它们的使用场景。

一、序列容器

std::array

固定大小数组,支持随机访问。

大小在编译时确定,栈上分配内存。

使用场景:需要固定大小的数组,且大小在编译时已知。

std::vector

动态数组,支持随机访问。

在尾部插入/删除元素效率高(平均O(1)),在中间或头部插入/删除效率低(O(n))。

使用场景:需要动态数组,频繁随机访问,主要在尾部添加/删除元素。

std::deque

双端队列,支持在头尾快速插入/删除(O(1)),支持随机访问(但比vector慢)。

使用场景:需要频繁在头尾插入/删除元素,且需要随机访问。

std::list

双向链表,不支持随机访问,但可以在任意位置快速插入/删除(O(1)),但需要先找到位置(查找O(n))。

使用场景:需要频繁在任意位置插入/删除,且不需要随机访问。

std::forward_list

单向链表,比list更节省空间,但只能单向遍历。

使用场景:只需要单向遍历,且需要频繁插入/删除。

二、关联容器

std::set

存储唯一键的集合,按键排序。

插入、删除、查找的时间复杂度为O(log n)。

使用场景:需要有序集合,且元素唯一。

std::map

存储键值对,按键排序,键唯一。

插入、删除、查找的时间复杂度为O(log n)。

使用场景:需要有序键值对,键唯一。

std::multiset

类似set,但允许重复键。

使用场景:需要有序集合,且允许重复。

std::multimap

类似map,但允许重复键。

使用场景:需要有序键值对,且允许重复键。

三、无序关联容器

std::unordered_set

存储唯一键的集合,使用哈希表实现,无序。

插入、删除、查找的平均时间复杂度为O(1),最坏情况O(n)。

使用场景:需要快速查找,且不关心顺序。

std::unordered_map

存储键值对,使用哈希表实现,无序。

插入、删除、查找的平均时间复杂度为O(1),最坏情况O(n)。

使用场景:需要快速查找键值对,且不关心顺序。

std::unordered_multiset

类似unordered_set,但允许重复键。

使用场景:需要快速查找,允许重复,不关心顺序。

std::unordered_multimap

类似unordered_map,但允许重复键。

使用场景:需要快速查找键值对,允许重复键,不关心顺序。

四、容器选择建议

选择容器时,考虑以下因素:

元素顺序:是否需要有序?如果需要有序,选择关联容器;如果不需要,考虑无序容器或序列容器。

插入/删除操作:在什么位置插入/删除?如果主要在尾部,用vector;在头尾,用deque;在中间,且频繁插入/删除,用list或forward_list。

随机访问:是否需要随机访问?如果需要,选择vector、deque、array;如果不需要,考虑list或forward_list。

查找性能:是否需要频繁查找?如果需要,考虑关联容器(有序则map/set,无序则unordered_map/unordered_set)。

内存开销:考虑容器的内存布局和额外开销。例如,list和forward_list有指针开销,unordered系列有哈希表开销。

五、代码示例

下面是一些容器的基本使用方法:

vector

cpp
#include <vector>
std::vector<int> vec = {1, 2, 3};
vec.push_back(4); // 在尾部插入
int element = vec[0]; // 随机访问
list

cpp
#include <list>
std::list<int> lst = {1, 2, 3};
lst.push_front(0); // 在头部插入
lst.insert(++lst.begin(), 5); // 在第二个位置插入
map

cpp
#include <map>
std::map<std::string, int> m;
m["apple"] = 5;
m["banana"] = 3;
// 遍历时按键排序,输出先apple后banana
unordered_map

cpp
#include <unordered_map>
std::unordered_map<std::string, int> um;
um["apple"] = 5;
um["banana"] = 3;
// 遍历顺序不确定
六、总结

根据具体需求选择合适的容器是关键。例如,在过敏测试的例子中,我们使用unordered_map来存储过敏原和分数的映射,因为我们需要快速查找,且不关心顺序。使用unordered_set来存储当前过敏原,因为我们需要快速查找和去重,且不关心顺序。

C++容器详细指南:使用方法与场景对比

1. 序列容器 (Sequence Containers)

1.1 std::vector - 动态数组

使用方法:

#include <vector>
#include <algorithm>

std::vector<int> vec = {1, 2, 3};
vec.push_back(4);           // 尾部添加
vec.pop_back();            // 尾部删除
vec.insert(vec.begin() + 1, 5); // 中间插入
vec.erase(vec.begin());    // 删除第一个元素

// 遍历
for (auto& elem : vec) {
    std::cout << elem << " ";
}

// 排序
std::sort(vec.begin(), vec.end());

使用场景:

  • ✅ 适合:随机访问、尾部频繁插入删除、需要连续内存
  • ❌ 不适合:频繁在头部或中间插入删除
  • 性能特点:访问O(1),尾部插入删除平均O(1),中间插入删除O(n)

1.2 std::list - 双向链表

使用方法:

#include <list>

std::list<int> lst = {1, 2, 3};
lst.push_front(0);         // 头部添加
lst.push_back(4);          // 尾部添加
lst.pop_front();           // 头部删除
lst.insert(++lst.begin(), 5); // 中间插入

// 特殊操作:拼接(O(1)时间复杂度)
std::list<int> lst2 = {6, 7, 8};
lst.splice(lst.end(), lst2);

// 排序(比vector慢,但保持迭代器有效)
lst.sort();

使用场景:

  • ✅ 适合:频繁在任意位置插入删除、需要稳定的迭代器
  • ❌ 不适合:需要随机访问、内存敏感的场景
  • 性能特点:插入删除O(1),访问O(n)

1.3 std::deque - 双端队列

使用方法:

#include <deque>

std::deque<int> dq = {1, 2, 3};
dq.push_front(0);          // 头部添加
dq.push_back(4);           // 尾部添加
dq.pop_front();            // 头部删除
dq.pop_back();             // 尾部删除

// 支持随机访问
std::cout << dq[1];        // O(1)访问

使用场景:

  • ✅ 适合:需要频繁在头尾插入删除、同时需要随机访问
  • ❌ 不适合:需要连续内存的场景
  • 性能特点:头尾插入删除O(1),中间操作O(n)

2. 关联容器 (Associative Containers)

2.1 std::set / std::multiset - 有序集合

使用方法:

#include <set>

std::set<int> s = {3, 1, 4, 1, 5}; // {1, 3, 4, 5}
s.insert(2);                        // 自动排序
s.erase(3);                         // 删除元素

// 查找
auto it = s.find(4);                // O(log n)
if (it != s.end()) {
    std::cout << "Found: " << *it;
}

// 范围查找
auto lower = s.lower_bound(2);      // 第一个>=2的元素
auto upper = s.upper_bound(4);      // 第一个>4的元素

// multiset允许重复
std::multiset<int> ms = {1, 1, 2, 2};

使用场景:

  • ✅ 适合:需要有序数据、频繁查找、自动去重(set)
  • ❌ 不适合:需要随机访问、内存极度敏感
  • 性能特点:插入删除查找都是O(log n)

2.2 std::map / std::multimap - 有序映射

使用方法:

#include <map>

std::map<std::string, int> age_map;
age_map["Alice"] = 25;
age_map["Bob"] = 30;

// 插入方式
age_map.insert({"Charlie", 28});
age_map.emplace("David", 32);

// 遍历(按键排序)
for (const auto& [name, age] : age_map) {
    std::cout << name << ": " << age << std::endl;
}

// 查找
auto it = age_map.find("Alice");
if (it != age_map.end()) {
    std::cout << "Alice's age: " << it->second;
}

使用场景:

  • ✅ 适合:键值对映射、需要按键排序、频繁查找
  • ❌ 不适合:只需要存储值、对内存要求严格
  • 性能特点:操作都是O(log n)

3. 无序关联容器 (Unordered Associative Containers)

3.1 std::unordered_set / std::unordered_multiset

使用方法:

#include <unordered_set>

std::unordered_set<std::string> us = {"apple", "banana"};
us.insert("orange");
us.erase("apple");

// 查找效率高
if (us.contains("banana")) {  // C++20
    std::cout << "Has banana";
}

使用场景:

  • ✅ 适合:需要快速查找、不关心顺序、需要去重
  • ❌ 不适合:需要有序遍历、哈希冲突严重的场景
  • 性能特点:平均O(1),最坏O(n)

3.2 std::unordered_map / std::unordered_multimap

使用方法:

#include <unordered_map>

std::unordered_map<std::string, int> word_count;
word_count["hello"] = 1;
word_count["world"]++;

// 遍历(无序)
for (const auto& [word, count] : word_count) {
    std::cout << word << ": " << count << std::endl;
}

4. 容器适配器 (Container Adapters)

4.1 std::stack - 栈

#include <stack>
std::stack<int> stk;
stk.push(1);
stk.push(2);
int top = stk.top();  // 2
stk.pop();            // 移除2

4.2 std::queue - 队列

#include <queue>
std::queue<int> q;
q.push(1);
q.push(2);
int front = q.front(); // 1
q.pop();              // 移除1

4.3 std::priority_queue - 优先队列

#include <queue>
std::priority_queue<int> pq;  // 最大堆
pq.push(3);
pq.push(1);
pq.push(4);
int top = pq.top();  // 4 (最大值)
pq.pop();           // 移除4

5. 详细对比表格

容器底层结构插入性能查找性能内存使用迭代器稳定性使用场景
vector动态数组尾部O(1)O(1)紧凑插入可能失效通用、随机访问
list双向链表任意O(1)O(n)每个元素额外开销稳定频繁插入删除
deque分块数组头尾O(1)O(1)中等插入可能失效双端队列
set/map红黑树O(log n)O(log n)中等稳定有序数据
unordered_set/map哈希表平均O(1)平均O(1)较高插入可能失效快速查找

6. 实际选择建议

根据操作频率选择:

// 场景1:主要随机访问,偶尔修改
std::vector<int> data;  // 最佳选择

// 场景2:频繁在任意位置插入删除
std::list<int> data;    // 链表更合适

// 场景3:需要快速查找,不关心顺序
std::unordered_set<std::string> dictionary;

// 场景4:需要有序数据,频繁范围查询
std::set<int> sorted_data;

性能测试示例:

#include <chrono>
#include <vector>
#include <list>

void test_performance() {
    const int N = 100000;
    
    // Vector测试
    std::vector<int> vec;
    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < N; ++i) {
        vec.insert(vec.begin(), i);  // 头部插入 - 很慢!
    }
    auto end = std::chrono::high_resolution_clock::now();
    
    // List测试  
    std::list<int> lst;
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < N; ++i) {
        lst.push_front(i);  // 头部插入 - 很快!
    }
    end = std::chrono::high_resolution_clock::now();
}

7. 最佳实践总结

  1. 默认选择:std::vector - 在不确定时总是首选
  2. 需要快速查找:std::unordered_map/set
  3. 需要有序数据:std::map/set
  4. 频繁插入删除:std::list(如果不需要随机访问)
  5. 内存敏感:避免链表和哈希表,优先考虑vector
  6. 线程安全:所有STL容器都不是线程安全的,需要外部同步

选择正确的容器可以显著影响程序性能和内存使用,理解每种容器的特性是写出高效C++代码的关键。

C++轮子(3) · STL关联容器 我们知道 Concept 表示的不是一个类型而是一个类型集合,所以 Refinement 表示的其实也是一个类型集合,这些类型比 Concept 中的定义的类型要有更多的约束和特性(约束和特性其实是一个问题的两个方面,你约束的越是严格,你能够使用的特性越多,但是你能使用的场景越少,比如 Java 中 Object 类哪儿都能用,又哪儿都用不了)。如果你在你的程序中需要查找最吻合的某个值(比如上面例子中的找到给定分辨率最合适的比特率),你可以使用上面提到的这几个函数,它们可以在logn之内找到给定的位置。 阅读详情

相关推荐

C++ 容器详解

顺序容器:此处的顺序不是体现在元素的值的顺序,而是指的是元素加入容器时的位置相对应的。 关联容器:顺序容器分类: 类型 特点 vector 可变大小数组 支持快速随机访 在尾部之外的位置插入或删除元素可能很慢。 deque 双端队列 支持快速随机访问 在头尾位置插入/删除速度很快 list 双向链表 只支持双向顺序访问 在list的

暖心~的博客 6761

C++学习笔记08--序列与关联容器

STL容器介绍

weixin_51114234的博客 469

C++中STL容器相关知识点序列容器、关联容器、迭代器 总结文档/PPT

C++中STL容器相关知识点序列容器、关联容器、迭代器 总结文档/ppt

m0_46183615的博客 1154

【C++基础】第9章:序列与关联容器

序列与关联容器1 容器概述1.1 容器:一种特殊的类型,其对象可以放置其它类型的对象(元素)1.1.1 需要支持的操作:对象的添加、删除、索引、遍历1.1.2 有多种算法可以实现容器,每种方法各有利弊1.2 容器分类1.2.1 序列容器:其中的对象有序排列,使用整数值进行索引1.2.2 关联容器:其中的对象顺序并不重要,使用键进行索引1.2.3 适配器:调整原有容器的行为,使得其对外展现出新的类型、接口或返回新的元素1.2.4 生成器:构造元素序列1.3 迭代器:用于指定容器中的一段区间,以执行遍历、删除等

qq_60225495的博客 3521

C++ | STL之顺序容器、关联容器、容器适配器

文章目录STL简述STL六大组件顺序容器(序列式容器)vectordequelist关联容器容器适配器 STL简述 STL是Standard Template Library的简称,中文名标准模板库,从根本上说,STL是一些“容器”的集合,这些“容器”有list、vector、set、map等,STL也是算法和其他一些组件的集合。STL的目的是标准化组件,这样就不用重新开发,可以使用现成的组件。...

ZY-JIMMY 2377

c语言串口编程详解

串口: 一种异步通信接口,通常用于低速数据传输。RS-232: 最常见的串口标准,定义了电气特性、连接器和信号线。UART: 通用异步收发传输器,是实现串口通信的硬件模块。通过以上内容,你应能够理解并实现C语言在Windows和Linux平台上的串口编程。希望这本手册能帮助你在实际项目中顺利进行串口通信开发。如果有任何疑问或需要进一步的帮助,请随时提问。

jkzyx123的博客 2224

C++ 基础与深度分析 Chapter9 序列与关联容器(容器的概述、序列容器)

C++ 基础与深度分析 Chapter9 序列与关联容器(容器的概述、序列容器)

爱学习的大叔的博客 474

科研绘图神器Origin2024最新中文版安装教程:5分钟搞定所有配置

本文提供了一份详细的Origin2024中文版安装与配置指南。从系统环境核查、安装包获取验证,到分步安装、语言切换及关键初始设置,手把手教你5分钟完成所有基础配置。同时,指南还分享了首次启动后的个性化设置与高效绘图工作流,助你快速上手这款科研绘图神器,提升数据处理与图表制作效率。

weixin_29247219的博客 1042

C++基础第9章:序列与关联容器(2)——序列容器

array不支持增加和删除vector在内存中连续存储list基于链表,在内存中不是连续存储dequevector和list的折中,分为很多段,每一段都是连续存储的,不同段之间使用链表来链接提供了对字符串的专门支持。...

qq_42731705的博客 555

【课程设计】TCP/IP 应用环境中服务器的部署与实现

本项目旨在通过搭建一个虚拟网络环境,实现软路由系统的配置和服务器的搭建与测试。具体包括安装虚拟机 VMWare Workstation,安装 Windows Server 2003 操作系统,配置软路由系统(包括双网卡安装、协议配置和测试),以及搭建并测试 DHCP 服务、DNS 服务、WWW 服务、FTP 服务和 SMTP/POP3 服务。

weixin_74907236的博客 1524

【示波器专题】无源探头的常用附件

使用探头进行测试,我们不仅要知道探头的原理,还需要了解探头的常用附件及其使用方式,这样才能在尽可能在测试中提高效率且减少出错的概率

一点硬件 692

C++ 顺序容器和关联容器

总结C++ 顺序容器和关联容器的易错点。

qq_45712409的博客 660

ESD防护设计宝典(十九):元器件选型宝典——共模电感

然而,这位“大师”的脾气也颇为古怪,若设计者不解其性、用之不当,它非但不能抑制噪声,反而会引入信号完整性恶化、电源压降等新问题,甚至让您的系统EMC性能“雪上加霜”,导致项目在测试阶段功亏一篑。本文将带您深入共模电感的内在世界,从本质解析到参数详解,从设计陷阱到实战选型,全方位领悟其平衡艺术,掌握其应用核心,规避那些足以让项目翻车的致命陷阱。:这是存在于电路板内部的“家贼”。共模电感实质上是一个四端器件,它通过磁场的“加法”与“减法”运算,巧妙地实现了对共模噪声的抑制,同时为差模信号大开绿灯。

m0_56451176的博客 421

【C++】关联容器

介绍了关联容器中的map、set、multimap和multiset

dab112的博客 2249

36、真核生物RNA PolII启动子预测相关研究

本文综述了真核生物RNA聚合酶II启动子预测的研究进展,涵盖转录调控机制、核心启动子元件(如TATA框、INR、GC框)、转录因子结合位点预测的挑战与方法。介绍了基于权重矩阵、神经网络和隐马尔可夫模型等多种启动子预测算法,并探讨了启动子分类策略及评分加权方法。通过Hertz-Stormo-Hartzell流程和基因微阵列分析实例,展示了如何识别保守调控序列。文章还总结了当前预测技术的局限性,提出了整合多组学数据、开发深度学习模型、加强实验验证等未来研究方向,旨在提升启动子识别的准确性与生物学意义。

palm99的专栏 187

库存管理系统项目部署方案(基于jdk17)

不需要安装到服务器,运维本地安装就行,主要是用来编译前端代码的。构建完成后将dist文件夹复制到服务器内。

程序员诚哥 6373

C++ 容器库概述:序列容器、关联容器与无序关联容器的原理、性能与应用

C++ 容器库概述:序列容器、关联容器与无序关联容器的原理、性能与应用

祯的博客 1844

某易将军令口令纯算法还原py篇

算法开源,将军令口令算法。希望官方多多更新吧

任雪飘的博客 3909

C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程

C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(std::vector、std::array、std::list、std::deque)、关联容器(std::set、std::map)和无序容器(std::unordered_set、std:

平凡程序猿~的博客 7978

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

C++STL容器及其优缺点介绍

STL容器介绍及选择方式容器类型容器优缺点一 序列容器vectordequelistforward_list(C++11)queuepriority_queuestackarray二 关联容器setmultisetmapmultimap三 无序关联容器 容器类型 以前的11个容易分别是deque、list、queue、priority_queue、stack、vector、map、multimap、set、multiset和bitset(bitset是在比特级处理数据的容器)。C++11新增了forward

凡人只做一事 2618

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

C++基础与深度解析 | 序列容器 | 关联容器 | 适配器与生成器

C++ 标准库提供了多种容器,它们是用于存储和操作数据集合的模板类。每种容器都有其特定的用途和特点,以及支持的基本操作。

zwcslj的博客 1303

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

C++ 关联容器

C++关联容器分为有序和无序两类:有序容器(map/set)基于红黑树实现,元素自动排序,操作复杂度O(logN);无序容器(unordered_map/unordered_set)基于哈希表,平均复杂度O(1),但元素无序。关键区别在于有序性、性能特征和键要求。有序容器适合需要排序或范围查询的场景,无序容器则追求更快的单点查询。选择时需权衡排序需求、性能要求、数据规模和键类型特性。C++11新增的emplace操作比insert更高效,可减少临时对象创建。实际开发中应根据具体需求选择容器类型,并通过性能分

2401_82978699的博客 882

C++序列容器和关联容器

序列容器 vector 类 | Microsoft Docshttps://docs.microsoft.com/zh-cn/cpp/standard-library/vector-class?view=msvc-170创建矢量容器 矢量容器的容量和大小 访问矢量中的元素 在矢量中插入和删除元素 在矢量中存储类对象 矢量元素的排序 存储矢量中的指针 双端队列容器 deque 类 | Microsoft Docs详细了解:deque 类https:/...

hd51cc的博客 592

C++ | STL | 序列容器 | 关联容器

C++ | STL | 序列容器 | 关联容器 目录 C++ | STL | 序列容器 | 关联容器 1.前言 2.序列容器 2.1.vector容器 2.2.array容器 2.3.valarray容器 2.4.queue容器 2.5.deque容器 2.6.priority_queue容器 2.7.list容器 2.8.forward_list容器 2.9.bitset容器 2.10.stack容器 3.关联容器 3.1.set容器 3.2.multiset容器 3.

山城盛夏的博客 565

STL 配置器和容器,序列容器和关联容器总结

STL中定义了许多容器类型,这些类型在C++中非常实用。但是很多人却并没有理解为什么叫配置器和容器,下面做个总结: 序列容器:数组、vector、list、deque、stack、queue、heap、priority-queue。这些类型存放的内容为value,并且在排放的逻辑上是一种线性结构。其中,stack、queue为配置器。为什么称他们为配置器,而不是容器呢?配置器的意思:修改

Efren_Yang的专栏 2055

【C++基础】第六十四课:[关联容器]关联容器操作

【C++基础】系列博客为参考)一书,自己所做的读书笔记。

qq_34222839的博客 936
上一篇: DLADDR 动态绑定 多日志系统
下一篇: 对TCP粘包情况的拆包和组包示例C语言版
Milu_Jingyu
博客等级 码龄5年 835粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值