- C++
C++ std::list 零基础完整教程
- @ 2026-9-18 19:49:42
C++ std::list 零基础完整教程
std::list是双向链表容器,头文件:#include <list>特点:
- 双向链表,每个节点存数据 + 指向前、后节点的指针
- 随机访问很差,不能用
list[下标],不支持[]- 在中间插入、删除元素效率极高,不需要移动大量元素
- 迭代器(iterator)不会因为插入删除失效(被删元素迭代器除外)
- 元素不连续存放在内存,和
vector(连续数组)形成对比
⚠️重点:list 不能像数组一样用下标
lst[0] lst[1]!想要访问元素靠迭代器遍历。
常用成员函数表格
| 函数 | 作用 |
|---|---|
lst.size() |
返回当前元素个数 |
lst.empty() |
判断是否为空,空返回true |
lst.clear() |
清空所有元素 |
lst.push_back(x) |
尾部添加元素x |
lst.push_front(x) |
头部添加元素x(vector没有这个!list优势) |
lst.pop_back() |
删除尾部元素 |
lst.pop_front() |
删除头部元素 |
lst.front() |
获取第一个元素 |
lst.back() |
获取最后一个元素 |
lst.insert(iter, x) |
在迭代器iter位置前面插入x |
lst.erase(iter) |
删除迭代器iter指向的元素 |
lst.remove(x) |
删除容器中所有等于x的元素(list独有) |
lst.reverse() |
链表反转,倒序 |
lst.sort() |
链表内部排序,不需要sort算法,成员函数 |
lst.merge(lst2) |
把lst2合并到lst,lst2变空,要求两个list预先有序 |
完整示例代码,逐行注释
#include <iostream>
#include <list> // 使用std::list必须头文件
using namespace std;
int main()
{
// 1.定义list容器,存储int类型数据
list<int> lst1; // 创建空的int链表
list<int> lst2 = {10,20,30,40}; // 创建同时初始化4个元素
// ============增加元素============
lst1.push_back(100); // 在链表【尾部】压入 100
lst1.push_back(200);
lst1.push_front(50); // 在链表【头部】压入 50 → list特有高效操作
lst1.push_front(10);
// 现在 lst1: 10 , 50 , 100 , 200
// ============获取头尾元素============
cout << "链表第一个元素 front():" << lst1.front() << endl; //10
cout << "链表最后一个元素 back():" << lst1.back() << endl; //200
cout << "链表大小 size() = " << lst1.size() << endl; //4
cout << "是否为空 empty() = " << lst1.empty() << endl;//0(false)
// ============迭代器 iterator 遍历list============
// list不能用 []下标!!只能用迭代器遍历
cout << "\n迭代器遍历lst1:" << endl;
// list<int>::iterator 迭代器类型,相当于链表的"指针"
for(list<int>::iterator it = lst1.begin(); it != lst1.end(); it++)
{
// *it 取出迭代器指向的数据
cout << *it << " ";
}
cout << endl;
// C++11 范围for循环,更简单,推荐日常写
cout << "范围for遍历:" << endl;
for(int num : lst1)
{
cout << num << " ";
}
cout << endl;
// ============insert 在指定位置插入元素============
// begin() 返回指向第一个元素的迭代器
auto it = lst1.begin(); // auto自动推导类型,等价 list<int>::iterator
it++; // it向后移动一步,指向第二个元素(50)
lst1.insert(it, 666); // 在it位置前面插入666
// 链表变成:10 , 666 , 50 , 100 , 200
// ============erase 删除迭代器指向的元素============
it = lst1.begin();
it++;
lst1.erase(it); // 删除it指向的666
// 链表回到:10 ,50 ,100 ,200
// ============remove 删除所有等于某个值的元素【list独有】============
lst1.push_back(50);
lst1.push_back(50);
// lst1: 10,50,100,200,50,50
lst1.remove(50); // 删除全部值=50的元素
// lst1:10,100,200
// ============reverse() 反转链表============
lst1.reverse();
cout << "\nreverse反转之后:" << endl;
for(int num : lst1) cout << num << " ";
cout << endl;
//输出:200 100 10
// ============sort() list自带排序成员函数============
lst1.sort(); // 默认从小到大升序
cout << "sort排序后:" << endl;
for(int num : lst1) cout << num << " ";
cout << endl;
//输出:10 100 200
// ============merge合并两个有序list============
list<int> la = {1,3,5};
list<int> lb = {2,4,6};
la.merge(lb); // lb全部合并进la,lb变为空链表
cout << "\nmerge合并结果 la:" << endl;
for(int x : la) cout << x << " ";
cout << " lb.size()=" << lb.size() << endl;
// ============pop 删除头、尾元素============
lst1.pop_front(); // 删除头部元素
lst1.pop_back(); // 删除尾部元素
// ============clear清空全部元素============
lst1.clear();
cout << "\nclear之后 size=" << lst1.size() << endl;
return 0;
}
迭代器基础说明
lst.begin() // 返回迭代器:指向链表第一个元素
lst.end() // 返回迭代器:指向【最后一个元素的后面】,不是有效元素!
it++:迭代器向后移动到下一个节点(list可以it++ it--双向移动)- list迭代器不支持
it + 3这种跳跃!不能直接跳几步,只能一步一步++/--
❌错误写法:
it = lst.begin() + 2;list不允许!vector可以。 ✅正确:it++; it++;
list vs vector 对比(重点,考试、写代码必看)
| 特性 | std::list(双向链表) | std::vector(动态数组) |
|---|---|---|
| 内存存储 | 内存不连续,节点分散 | 内存连续一块空间 |
随机访问 [下标] |
❌不支持 | ✅支持 |
| 头部插入删除 | ⭐极快 O(1) | 慢,需要移动全部元素 O(n) |
| 尾部插入删除 | 快 | ⭐极快 |
| 中间插入删除 | ⭐极快 O(1) | 慢 O(n) |
| 迭代器失效 | 删除元素,仅被删元素迭代器失效 | 插入删除会大量迭代器失效 |
| 排序 | 自带.sort()成员函数 |
用全局sort()算法 |
使用场景选择:
- 需要频繁在头部、中间插入删除 → 优先 list
- 需要频繁按下标访问数据,尾部增删 → 优先 vector
常见坑点
- ❌不能写
list<int> a; cout << a[0];list没有下标运算符!编译报错 it + n跳跃迭代器不能用于list,只能it++、it--一步移动merge()合并前两个list最好预先有序;merge之后第二个list会变成空remove(x)直接删除所有等于x的元素,vector没有这个函数- end()是末尾后面,不是最后一个元素,循环条件一定写
it != lst.end()
小练习
- 创建list,依次插入 1,2,3,4,5;头部插入0;尾部插入6;遍历输出
- 删除所有等于3的元素,反转链表输出
- 两个有序list做merge合并输出
0 条评论
目前还没有评论...