【C++指南】STL list容器完全解读(一):从入门到把握根本操作

[复制链接]
发表于 2025-9-17 22:28:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
.
   💓 博客主页:倔强的石头的CSDN主页
📝Gitee主页:倔强的石头的gitee主页
⏩ 文章专栏:《C++指南》
期待您的关注
  

  

一、初识list容器

1.1 什么是list?

在C++标准模板库(STL)中,list是一个基于双向链表实现的序列容器。它允许在恣意位置举行高效插入和删除操作,时间复杂度为O(1)。与vector差异,list不保证元素在内存中的一连存储,因此不支持随机访问。

1.2 焦点特性



  • 双向链表结构:每个元素包含指向前后节点的指针
  • 动态内存分配:元素按需分配内存
  • 高效插入删除:无需移动其他元素
  • 迭代器稳固性:插入删除操作不会使已有迭代器失效(除被删除元素)
1.3 范例应用场景



  • 须要频仍在首尾之外的位置插入/删除元素
  • 元素体积较大,制止vector扩容时的拷贝开销
  • 须要维护元素的插入次序
  • 须要归并、拆分链表等特殊操作
二、焦点成员函数

2.1 默认成员函数


构造函数的重载版本

函数功能形貌示例默认构造函数创建空listlist<int> lst1;添补构造函数创建包含n个元素的listlist<char> lst2(5);拷贝构造函数复制另一个list的内容list<int> lst3(lst2);移动构造函数(C++11)转移另一个list的资源list<int> lst4(move(lst3));析构函数自动开释内存(通常无需手动调用)lst1.~list();拷贝赋值运算符深拷贝赋值操作lst2 = lst1;移动赋值运算符(C++11)高效转移资源赋值操作lst3 = move(lst2);
  1. // 初始化列表构造(C++11)
  2. list<string> fruits {"apple", "banana", "cherry"};
复制代码

三、迭代器操作


3.1 根本迭代器

函数功能示例begin()返回指向第一个元素的迭代器auto it = lst.begin();end()返回末端哨兵迭代器while(it != lst.end())rbegin()返回反向起始迭代器auto rit = lst.rbegin();rend()返回反向结束迭代器for(; rit != lst.rend();)3.2 常量迭代器(C++11)

函数功能示例cbegin()返回不可修改的正向起始迭代器auto cit = lst.cbegin();cend()返回不可修改的正向结束迭代器if(cit == lst.cend())crbegin()返回不可修改的反向起始迭代器auto crit = lst.crbegin();crend()返回不可修改的反向结束迭代器while(crit != lst.crend())
  1. list<int> nums {1,2,3};
  2. // 正向遍历
  3. for(auto it = nums.begin(); it != nums.end(); ++it) {
  4.     cout << *it << " ";  // 输出:1 2 3
  5. }
复制代码

四、容量与访问操作


4.1 容量查询

函数功能示例size()返回元素数目if(lst.size() > 5)empty()判定容器是否为空while(!lst.empty())4.2 元素访问

函数功能示例front()访问首元素(可修改)lst.front() = 10;back()访问尾元素(可修改)cout << lst.back();
  1. list<double> temps {36.5, 37.1, 38.0};
  2. temps.front() = 35.9;  // 修改首元素
  3. cout << "当前体温:" << temps.back();  // 输出38.0
复制代码

五、修改操作详解


5.1 根本修改函数

函数功能示例push_front(val)头部插入元素lst.push_front(0);emplace_front(args)头部直接构造元素lst.emplace_front("test");pop_front()删除头部元素lst.pop_front();push_back(val)尾部插入元素lst.push_back(100);emplace_back(args)尾部直接构造元素lst.emplace_back(1,2);pop_back()删除尾部元素lst.pop_back();clear()清空全部元素lst.clear();push_back vs emplace_back:
  1. class Student {
  2. public:
  3.     Student(int id, string name) : id(id), name(name) {}
  4. private:
  5.     int id;
  6.     string name;
  7. };
  8. list<Student> roster;
  9. roster.push_back(Student(101, "Alice"));  // 构造临时对象+拷贝
  10. roster.emplace_back(102, "Bob");         // 直接构造(高效)
复制代码
5.2 高级修改操作

函数功能示例assign(n, val)用n个val更换内容lst.assign(5, 0);assign(beg, end)用迭代器范围更换内容lst.assign(vec.begin(), vec.end());swap(other)互换两个list的内容lst1.swap(lst2);resize(n)调解元素数目lst.resize(10);resize(n, val)调解数目并用val添补新增元素lst.resize(15, -1);
  1. list<int> nums;
  2. nums.assign({1,2,3});       // 内容变为[1,2,3]
  3. nums.resize(5);             // 变为[1,2,3,0,0]
  4. nums.resize(3);             // 截断为[1,2,3]
复制代码
5.3 插入与删除

insert重载版本

  1. iterator insert(iterator pos, const T& val);  // 单元素插入
  2. void insert(iterator pos, size_t n, const T& val); // 批量插入
  3. void insert(iterator pos, InputIt first, InputIt last); // 范围插入
复制代码
erase操作

  1. iterator erase(iterator pos);                 // 删除单个元素
  2. iterator erase(iterator first, iterator last); // 删除区间元素
复制代码
示例:
  1. list<int> data {10,20,30};
  2. auto it = data.begin();
  3. advance(it, 1);
  4. data.insert(it, 15);        // [10,15,20,30]
  5. data.insert(it, 2, 18);     // [10,15,18,18,20,30]
  6. vector<int> tmp {25,35};
  7. data.insert(data.end(), tmp.begin(), tmp.end()); // 末尾追加
  8. data.erase(it);             // 删除第二个18
复制代码

六、特殊成员函数


6.1 条件操作

函数功能示例remove(val)删除全部即是val的元素lst.remove(5);remove_if(pred)删除满意条件的元素lst.remove_if([](int n){ return n%2==0; });
  1. list<int> nums {1,2,3,2,5};
  2. nums.remove(2);  // 删除所有2 → [1,3,5]
  3. nums.remove_if([](int x){ return x>3; }); // → [1,3]
复制代码
6.2 链表特有操作

函数功能示例unique()删除一连重复元素lst.unique();merge(other)归并有序链表lst1.merge(lst2);sort()排序元素(升序)lst.sort();splice(pos, other)转移另一个链表的元素lst1.splice(it, lst2);
  1. list<int> a {1,3,5}, b {2,4,6};
  2. a.merge(b);       // a变为[1,2,3,4,5,6], b为空
  3. a.sort();         // 排序(若未有序)
  4. list<int> x {10,20}, y {30,40};
  5. auto pos = x.begin();
  6. x.splice(pos, y); // x变为[30,40,10,20], y为空
复制代码

七、总结与进阶

本文详细先容了C++ list容器的根本特性和使用方法。通过大量的代码示例,我们学习了怎样准确使用list举行元素的增编削查操作。list作为STL中紧张的序列式容器,其独特的链表结构使其在特定场景下具有不可替代的上风。
在接下来的系列文章中,我们将深入探究:


  • list的高级应用本领
  • list在实际项目中的最佳实践案例
下篇预告:《【C++指南】C++ list容器完全解读(二):list模拟实现,底层架构揭秘》,我们将通过分析STL源码实现,带你明白list的底层工作机制
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表