news 2026/6/10 1:10:56

C++ STL list容器深度解析与模拟实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++ STL list容器深度解析与模拟实现

📚 一、list容器介绍

1.1 基本概念

list是C++标准模板库(STL)中的一个序列容器,底层实现为带头节点的双向循环链表。这种结构使得list在任意位置插入和删除元素都具有很高的效率。

1.2 核心特性

  • 双向访问:可以从前后两个方向遍历

  • 动态内存:每个元素独立分配内存(节点)

  • 迭代器类型:双向迭代器(支持++和--操作)

  • 内存不连续:元素在内存中不是连续存储的

🔧 二、list的基本使用

2.1 构造函数

cpp

#include <list> #include <iostream> void test_construction() { // 1. 默认构造 - 空list std::list<int> list1; // 2. 构造包含n个相同元素的list std::list<int> list2(5, 100); // 5个100 // 3. 范围构造 int arr[] = {1, 2, 3, 4, 5}; std::list<int> list3(arr, arr + 5); // 4. 拷贝构造 std::list<int> list4(list3); // 5. 初始化列表构造(C++11) std::list<int> list5 = {1, 2, 3, 4, 5}; }

2.2 迭代器使用

cpp

void test_iterator() { std::list<int> lst = {1, 2, 3, 4, 5}; // 正向迭代器 std::cout << "正向遍历: "; for (auto it = lst.begin(); it != lst.end(); ++it) { std::cout << *it << " "; } std::cout << std::endl; // 反向迭代器 std::cout << "反向遍历: "; for (auto rit = lst.rbegin(); rit != lst.rend(); ++rit) { std::cout << *rit << " "; } std::cout << std::endl; // C++11范围for循环 std::cout << "范围for遍历: "; for (int val : lst) { std::cout << val << " "; } std::cout << std::endl; }

2.3 容量操作

cpp

void test_capacity() { std::list<int> lst = {1, 2, 3}; std::cout << "是否为空: " << lst.empty() << std::endl; std::cout << "元素个数: " << lst.size() << std::endl; // list没有capacity()方法,因为链表不需要预分配空间 }

2.4 元素访问

cpp

void test_element_access() { std::list<int> lst = {1, 2, 3, 4, 5}; if (!lst.empty()) { std::cout << "第一个元素: " << lst.front() << std::endl; std::cout << "最后一个元素: " << lst.back() << std::endl; } // list不支持随机访问,所以没有operator[]和at()方法 // 要访问第n个元素,需要遍历 }

2.5 修改操作

cpp

void test_modifiers() { std::list<int> lst; // 头部操作 lst.push_front(10); // 头部插入 lst.pop_front(); // 头部删除 // 尾部操作 lst.push_back(20); // 尾部插入 lst.pop_back(); // 尾部删除 // 中间插入 auto it = lst.begin(); ++it; // 移动到第二个位置 lst.insert(it, 30); // 在第二个位置插入30 // 删除 it = lst.begin(); lst.erase(it); // 删除第一个元素 // 清空 lst.clear(); }

⚠️ 三、迭代器失效问题

3.1 错误示例

cpp

// 错误写法:迭代器失效 void wrong_example() { std::list<int> lst = {1, 2, 3, 4, 5}; auto it = lst.begin(); while (it != lst.end()) { lst.erase(it); // 错误!删除后it失效 ++it; // 使用失效的迭代器,未定义行为 } }

3.2 正确写法

cpp

// 正确写法1:使用返回值更新迭代器 void correct_example1() { std::list<int> lst = {1, 2, 3, 4, 5}; auto it = lst.begin(); while (it != lst.end()) { it = lst.erase(it); // erase返回下一个有效迭代器 } } // 正确写法2:后置递增 void correct_example2() { std::list<int> lst = {1, 2, 3, 4, 5}; auto it = lst.begin(); while (it != lst.end()) { lst.erase(it++); // 先传递it,然后递增 } }

注意:对于list,只有指向被删除元素的迭代器会失效,其他迭代器不受影响。

🔨 四、list的模拟实现

4.1 节点结构

cpp

template<class T> struct ListNode { ListNode<T>* _prev; ListNode<T>* _next; T _data; ListNode(const T& val = T()) : _prev(nullptr) , _next(nullptr) , _data(val) {} };

4.2 list类框架

cpp

template<class T> class List { private: ListNode<T>* _head; // 头节点(哨兵节点) public: // 迭代器类 class iterator { private: ListNode<T>* _node; public: iterator(ListNode<T>* node = nullptr) : _node(node) {} // 前置++ iterator& operator++() { _node = _node->_next; return *this; } // 后置++ iterator operator++(int) { iterator temp(*this); _node = _node->_next; return temp; } // 解引用 T& operator*() { return _node->_data; } // 箭头运算符 T* operator->() { return &_node->_data; } // 比较运算符 bool operator!=(const iterator& it) { return _node != it._node; } bool operator==(const iterator& it) { return _node == it._node; } }; // 构造函数 List() { _head = new ListNode<T>(); _head->_prev = _head; _head->_next = _head; } // 析构函数 ~List() { clear(); delete _head; _head = nullptr; } iterator begin() { return iterator(_head->_next); } iterator end() { return iterator(_head); } // 插入、删除等其他方法... };

4.3 反向迭代器实现

cpp

template<class Iterator> class ReverseIterator { private: Iterator _it; public: ReverseIterator(Iterator it) : _it(it) {} // 前置++ ReverseIterator& operator++() { --_it; return *this; } // 后置++ ReverseIterator operator++(int) { ReverseIterator temp(*this); --_it; return temp; } // 解引用(注意反向迭代器的特殊处理) typename Iterator::reference operator*() { Iterator temp = _it; --temp; return *temp; } // 其他必要操作... };

📊 五、list与vector对比

特性vectorlist
底层结构动态数组,连续内存双向链表,非连续内存
随机访问O(1)(支持)O(n)(不支持)
插入/删除尾部O(1),其他位置O(n)任意位置O(1)(已知位置)
内存使用连续,缓存友好,空间利用率高碎片化,缓存不友好,每个元素额外开销
迭代器类型随机访问迭代器双向迭代器
迭代器失效插入/删除可能导致全部迭代器失效只有被删除元素的迭代器失效
适用场景需要随机访问,尾部操作频繁频繁在任意位置插入/删除

🎯 六、选择指南

使用vector的场景:

  • 需要频繁随机访问元素

  • 元素数量变化不大,主要在尾部操作

  • 对缓存性能要求高

  • 需要与其他C函数或库交互(连续内存)

使用list的场景:

  • 频繁在中间位置插入/删除元素

  • 不需要随机访问,主要是顺序访问

  • 元素较大,移动成本高

  • 需要稳定的迭代器(不被插入操作影响)

💡 七、最佳实践

  1. 优先选择vector:除非有明确的理由,否则vector通常是更好的选择

  2. 考虑deque:如果需要头尾高效操作,考虑使用deque

  3. 使用算法库:结合STL算法(如sort、find等)使用

  4. 注意迭代器失效:特别是在循环中修改容器时

总结

list作为STL中的双向链表容器,在特定场景下具有不可替代的优势。理解其底层实现原理、迭代器机制以及与vector的区别,能够帮助我们在实际开发中做出更合理的选择。通过模拟实现list,我们能够更深入地理解STL容器的设计思想,提升C++编程能力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 22:39:32

大模型推理成本居高不下?TensorRT镜像帮你节省70%开销

大模型推理成本居高不下&#xff1f;TensorRT镜像帮你节省70%开销 在大模型落地越来越普遍的今天&#xff0c;一个现实问题摆在每个AI工程团队面前&#xff1a;为什么训练完的模型一上线&#xff0c;GPU账单就猛增&#xff1f;明明A100卡跑着&#xff0c;QPS却卡在几十&#xf…

作者头像 李华
网站建设 2026/6/9 21:14:33

项目应用:整车厂UDS诊断一致性测试方案

整车厂如何打赢UDS诊断一致性这场“隐形战役”&#xff1f;你有没有遇到过这样的场景&#xff1a;一款新车即将量产&#xff0c;各个ECU陆续到货&#xff0c;测试团队一通操作猛如虎——结果诊断仪连不上某个模块&#xff1b;或是刷写时突然报错“安全访问失败”&#xff0c;查…

作者头像 李华
网站建设 2026/6/9 22:31:41

Keil4下STM32项目移植到其他型号实践指南

Keil4下STM32项目跨型号移植实战全解析在嵌入式开发的日常中&#xff0c;你是否曾遇到这样的场景&#xff1a;原本跑得好好的STM32F103项目突然要迁移到性能更强的STM32F407&#xff1f;或者因为供应链问题不得不换一款引脚兼容但系列不同的芯片&#xff1f;更头疼的是——这一…

作者头像 李华
网站建设 2026/6/9 21:18:44

NVIDIA TensorRT在体育分析中的应用前景

NVIDIA TensorRT在体育分析中的应用前景 在一场职业足球比赛的直播中&#xff0c;导播需要从多个机位中实时选择最佳画面&#xff0c;同时系统要自动识别出关键事件——比如一次精彩的过人、一记远射&#xff0c;或是潜在的犯规动作。这些看似即时的操作背后&#xff0c;是一整…

作者头像 李华
网站建设 2026/6/9 22:37:28

基于TensorRT的智慧农业病虫害识别系统

基于TensorRT的智慧农业病虫害识别系统 在一片广袤的果园里&#xff0c;高清摄像头正持续捕捉着每一片树叶的细微变化。突然&#xff0c;系统检测到几处叶片出现斑点状病变——不到50毫秒后&#xff0c;预警信息已推送至农技人员手机&#xff0c;并自动调度无人机前往定点喷洒药…

作者头像 李华
网站建设 2026/6/9 22:37:57

NVIDIA TensorRT在文化遗产数字化中的应用

NVIDIA TensorRT在文化遗产数字化中的应用 想象一下&#xff0c;敦煌莫高窟的一幅千年壁画正被一台高精度扫描仪逐像素捕捉。接下来&#xff0c;AI模型要在几毫秒内完成破损区域识别与智能补全&#xff0c;以便研究人员实时预览修复效果——这不仅是艺术的重生&#xff0c;更是…

作者头像 李华