C++中list的使用方法及常用list操作总结

发布时间:2026/11/4 4:03:47

C++中list的使用方法及常用list操作总结 前言std::list是标准库提供的双向链表。每个节点单独分配节点之间用前驱、后继两个指针相连因此任意位置插入删除都是 O(1)代价是不能随机访问遍历时的内存局部性也不如连续容器。常见误解有三个。第一以为「链表插入删除快」就代表所有场景都该用list忽略了定位插入位置本身要 O(n) 遍历而且每个节点一次分配、缓存命中率低。第二把std::sort直接套在list上编译失败——std::sort要求随机访问迭代器list只提供双向迭代器。第三以为unique能去掉所有重复元素实际上它只删除相邻的重复通常要先sort。本文按结构特性、常用操作、专属算法、容器选择四部分讲代码以 C17 为准。一、结构与迭代器特性std::list的每个元素存放在独立节点里节点还保存前后指针。它提供双向迭代器bidirectional iterator支持、--不支持 n、- n、比较。要移动迭代器用std::advance、std::next、std::prev它们对链表是线性走步。C11 起list::size()要求常数时间实现通常在容器里维护一个计数更早的标准允许线性。list不提供operator[]、at()、data()也没有reserve()——它本来就不是连续存储。每个节点除了数据还要存两个指针外加分配器的开销所以同样元素数量下list的内存占用通常明显高于vector。这是「O(1) 插入」的代价。二、构造与基本操作list支持初始化列表构造、区间构造、n个相同值构造以及拷贝/移动构造。常用成员包括push_front、push_back、pop_front、pop_back、emplace_front、emplace_back、insert、emplace、erase、clear、resize、assign。// 适用于 C17#include iostream#include listint main() {std::listint values{1, 2, 3};values.push_front(0);values.emplace_back(4);auto it values.begin();std::advance(it, 2); // 不能写 it 2it values.insert(it, 99); // insert 返回新元素的迭代器std::cout *it \n;it values.erase(it); // 删除 99返回下一个位置std::cout *it \n;for (int v : values) std::cout v ;std::cout \n;}insert不会让其他迭代器失效erase只让被删元素的迭代器失效其余迭代器保持有效。这与vector很不一样vector扩容会让所有迭代器、指针、引用失效。也正因如此遍历中删除元素要写成it lst.erase(it);不能erase之后继续it。emplace系列把参数直接传给元素构造函数少一次临时对象对int看不出差别对自定义类型有意义。assign(count, value)和assign(first, last)会先清空再重新填入适合复用同一个容器对象避免反复构造销毁。resize(n)在变长时插入值初始化的元素变短时删除尾部元素对list来说resize不需要搬移但每个新节点仍是一次独立分配。clear()删除所有元素但保留容器对象本身之后可以继续使用。区间形式的erase(first, last)返回last可以一次删除一段。注意last是开区间端点不删除。对链表来说按区间删除仍然是逐个节点释放复杂度与区间长度成正比不会因为「知道首尾」就变成 O(1)。三、list 专属操作splice、merge、sort、unique这几个成员函数是list相对于其他容器的主要优势它们直接操作节点指针。// 适用于 C17#include iostream#include listint main() {std::listint a{3, 1, 2, 2, 4};a.sort(); // 成员函数排序稳定a.unique(); // 删除相邻重复排序后才等价于全局去重a.remove_if([](int x) { return x % 2 0; });std::listint b{9, 8};a.splice(a.end(), b); // 把 b 的全部节点接到 a 末尾b 变为空for (int x : a) std::cout x ;std::cout \n;}splice有三种形式整条链拼接到位置pos、拼接单个元素、拼接一个区间。它不复制、不移动元素只改指针因此原来指向被拼接元素的迭代器仍然有效只是所属容器变了。整条链的splice是常数时间跨容器拼接一个区间时标准给出的复杂度与区间长度相关使用前最好确认所用标准的措辞。C11 起两个list的分配器不相等时进行splice是 UB容器默认分配器时通常没有问题。merge把另一条已排序的链合并进来稳定且不复制节点。标准要求调用前两条链都有序对无序输入标准不保证结果不要拿它当「任意合并」用。sort是成员函数不是std::sort。它通常是归并实现稳定复杂度 O(n log n)只改指针不移动元素。unique删除相邻重复可以传二元谓词自定义「相等」如果不先排序它只能去掉连续出现的重复。remove(value)和remove_if(pred)会删除所有匹配元素内部也是遍历加 erase复杂度 O(n)。四、什么时候用 list操作std::liststd::vector随机访问不支持O(1)头部插入O(1)O(n)中间插入已有位置O(1)O(n)按值查找O(n)O(n)扩容不适用可能搬移全部元素迭代器失效仅被删元素扩容时全部失效内存局部性差好每元素额外开销两个指针 分配头通常无经验规则是数据量小、以遍历和随机访问为主用vector需要在已知位置频繁插入删除、或需要splice把节点在容器间搬家才考虑list。如果只是「频繁在头部插入」std::deque往往比list更合适因为它的块状存储仍有不错的局部性。在没有实际测量之前不要仅凭复杂度表就断定链表更快节点分配、指针跳转和缓存未命中都可能把 O(1) 的理论优势抵消掉。常见坑点❌lst[0]或lst.at(0)访问元素。✅ 用迭代器*lst.begin()需要下标就换vector/deque。❌it 1移动链表迭代器。✅ 用it、std::next(it)、std::advance(it, n)。❌std::sort(lst.begin(), lst.end())。✅ 用成员函数lst.sort()它稳定且只改指针。❌ 遍历中lst.erase(it); it;迭代器已失效。✅it lst.erase(it);❌ 以为unique会删除所有重复。✅ 先sort再unique或改用set/unordered_set去重。❌ 把未排序的两条链直接merge。✅ 先分别sort再merge或者用splice加统一排序。❌ 认为splice会复制元素、原容器仍保留。✅splice转移节点源容器不再拥有这些元素。❌ 用list存大量小对象并频繁遍历忽略缓存不友好。✅ 评估vector/deque必要时先做性能测量再决定。总结主题结论结构双向链表节点独立分配双向迭代器插入删除已知位置 O(1)定位仍要 O(n)专属操作splice、merge、sort、unique、remove_if迭代器插入不影响删除只影响被删元素适用场景频繁中间增删、节点跨容器转移std::list不是一个「更快的 vector」而是一个「用空间和局部性换节点操作」的容器。真正该用它的场景并不多需要splice在容器间零拷贝搬节点或者迭代器稳定性比遍历速度更重要。其余时候先考虑vector和deque通常能得到更简单也更快的代码。
延伸阅读

更多相关文章

2026/11/4 4:03:47

llama.cpp 加载 GGUF 模型:5.9GB 文件为何只占 2.7GB 显存?

1. 从一条日志说起:5.9GB 模型为什么只吃 2.7GB 显存先把结论摆在前面:模型文件大小和显存占用从来就不是一回事。我本地跑一个 5.9GB 的 GGUF 模型,nvidia-smi里看到进程显存稳定在 2.7GB 上下,第一次看到这个数字的时候我也愣了…

2026/11/4 4:03:47

LoongForge全链路优化GR00T N1.6训练实战

1. 项目概述:这不是一次简单的参数调优,而是一次全链路工程重构LoongForge 全链路优化 GR00T N1.6 训练——这个标题里每一个词都带着分量。“LoongForge”不是某个开源库的别名,而是我们团队内部代号为“龙锻”的自研训练加速框架&#xff0…

2026/11/4 3:58:47

麦克风阵列音频检查方法与标准:裸板到整机验收排查

简介:面向麦克风阵列研发、测试与硬件质量验证场景的《麦克风阵列音频检查方法与标准》,适合声学工程师、硬件测试人员及智能音箱、会议系统、语音识别设备开发者对照使用,重点解决研发阶段音频评测项目不清、判据不统一的问题。压缩包仅含1个…

2026/11/4 6:03:54

从零撸MQTT:协议原理、Broker搭建与物联网实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/4 6:03:54

ESP32-S3 Mini与C3 Mini采购指南:从参数对比到避坑清单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/4 6:03:54

EtherCAT从站原理与汇川H5U带24轴伺服配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/4 6:03:54

云边协同时钟同步实战:Chrony配置调优与监控告警指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/4 5:58:53

SCRFD人脸检测:300%性能提升的工程拆解与优化实践

人脸检测这个方向,这几年从“能检出”卷到了“又快又准又小”,真正能在生产环境里跑出漂亮指标的方案并不多。SCRFD 算是其中一个让我反复回看、反复拆解的实现——它把检测精度和推理效率这对老矛盾处理得相当漂亮,很多团队在边缘设备上做人…

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/4 0:03:20

AI辅助技术栈评估:提升研发决策效率60%

1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年…

2026/11/4 0:03:20

从生成Token到直接决策:Jev如何重塑AI Agent工程实践

1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你…

2026/11/4 0:03:20

32G统一内存跑大模型:内存账、TPS实测与端云分流

想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统…

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑