深入理解C++ 容器 std::list

发布时间:2026/10/13 18:45:08
深入理解C++ 容器 std::list std::list是 C 标准库list中的双向链表容器。它不要求元素连续存储每个元素单独放在一个节点里节点中保存前驱指针、后继指针和实际值。1. 核心特点底层结构双向链表每个节点独立分配。访问元素只能顺序访问不支持随机访问没有operator[]和at()。插入删除在已知迭代器位置插入/删除单个元素是O(1)且不会导致其他元素的迭代器失效。查找按值查找是O(n)。迭代器双向迭代器支持、--但不支持it n、it - n、比较。内存开销每个元素额外保存两个指针通常比std::vector更占内存。缓存友好性节点分散遍历时缓存局部性差通常比vector慢。2. 常用操作cpp#include list std::listint l {1, 2, 3}; l.push_back(4); // 尾部插入 l.push_front(0); // 头部插入 l.pop_back(); // 删除尾部 l.pop_front(); // 删除头部 l.insert(it, 10); // 在 it 前插入返回新元素迭代器 l.emplace(it, 10); // 在 it 前直接构造 l.erase(it); // 删除 it返回下一个迭代器 l.clear(); // 清空 l.front(); // 第一个元素 l.back(); // 最后一个元素 l.empty(); // 是否为空 l.size(); // 元素个数C11 后 O(1)链表特有操作cppl.sort(); // 成员函数稳定排序O(n log n) l.reverse(); // 反转 l.unique(); // 删除连续重复元素通常先 sort l.remove(3); // 删除所有等于 3 的元素 l.remove_if(pred); // 删除所有满足谓词的元素 l.merge(other); // 合并两个有序 list源 list 变空 l.splice(pos, other);// 把 other 的节点移动到 *this不拷贝元素注意std::sort不能用于std::list因为std::sort需要随机访问迭代器。必须用成员函数l.sort()。3. 迭代器失效规则insert、emplace、push_front、push_back不使任何迭代器失效。erase、pop_front、pop_back只使指向被删除元素的迭代器失效。splice、merge、sort、reverse不使迭代器失效只是重新链接节点。clear使所有迭代器失效。这是std::list相比std::vector的一大优势vector插入时可能重新分配导致所有迭代器失效。4. 与 vector 的简单对比特性std::liststd::vector存储非连续双向链表连续动态数组随机访问不支持O(n)支持O(1)中间插入删除O(1)已知位置O(n)迭代器失效插入不失效删除只失效被删插入可能全部失效内存开销每元素两个指针较小可能有预留容量缓存友好差好适用场景频繁中间插入删除、稳定迭代器频繁随机访问、尾部操作、遍历大多数情况下std::vector因为缓存友好实际性能可能更好。只有确实需要频繁在中间插入删除并且已经持有迭代器时std::list才更有优势。#include iostream #include list #include string #include algorithm #include iterator int main() { // 1. 基本操作 std::liststd::string tasks {write, test, deploy}; tasks.push_front(plan); tasks.push_back(monitor); auto it std::find(tasks.begin(), tasks.end(), test); if (it ! tasks.end()) { tasks.insert(it, code); // 在 test 前插入 code } std::cout tasks: ; for (const auto t : tasks) { std::cout t ; } std::cout \n; tasks.remove(deploy); // 删除所有 deploy std::cout after remove: ; for (const auto t : tasks) { std::cout t ; } std::cout \n; // 2. 排序、去重、反转 std::listint nums {3, 1, 2, 2, 5, 4}; nums.sort(); // list 成员函数稳定排序 nums.unique(); // 删除连续重复元素 nums.reverse(); // 反转 std::cout nums: ; for (int n : nums) { std::cout n ; } std::cout \n; // 3. splice把 b 的节点移动到 a 中不拷贝元素 std::listint a {1, 2, 3}; std::listint b {10, 20, 30}; auto pos std::next(a.begin()); // 指向 2 a.splice(pos, b); // 把 b 全部插入到 pos 之前 std::cout a: ; for (int n : a) { std::cout n ; } std::cout \n; std::cout b empty: std::boolalpha b.empty() \n; return 0; }

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询