forward_list是C++11引入的STL容器,属于单向链表结构,每个节点只存储指向下一个节点的指针,因此相比双向链表list内存开销更小,但是不支持反向遍历,也没有size方法直接获取元素个数。它适合在只需要顺序访问、频繁在头部插入删除元素的场景中使用。

forward_list的基本构造与初始化
forward_list支持多种构造方式,可以根据需求选择不同的初始化方法,以下是常见的构造示例:
#include <forward_list>
#include <iostream>
int main() {
// 默认构造空链表
std::forward_list<int> fl1;
// 初始化列表构造
std::forward_list<int> fl2 = {1, 2, 3, 4, 5};
// 构造包含n个相同元素的链表
std::forward_list<int> fl3(5, 10); // 5个元素,每个都是10
// 拷贝构造
std::forward_list<int> fl4(fl2);
// 移动构造
std::forward_list<int> fl5(std::move(fl2));
return 0;
}
元素插入操作
forward_list不支持随机访问,也没有push_back方法,只能在头部或者指定位置之后插入元素,插入操作需要借助迭代器完成。
头部插入
使用push_front方法可以在链表头部插入元素,时间复杂度为O(1):
#include <forward_list>
#include <iostream>
int main() {
std::forward_list<int> fl = {2, 3, 4};
// 头部插入元素1
fl.push_front(1);
// 遍历输出链表元素
for (int num : fl) {
std::cout << num << " ";
}
// 输出结果:1 2 3 4
return 0;
}
指定位置之后插入
由于是单向链表,无法获取前一个节点的迭代器,因此插入操作只能在给定迭代器指向的元素之后进行,使用insert_after方法:
#include <forward_list>
#include <iostream>
int main() {
std::forward_list<int> fl = {1, 3, 4};
// 获取第一个元素的迭代器
auto it = fl.begin();
// 在it指向的元素之后插入2
fl.insert_after(it, 2);
for (int num : fl) {
std::cout << num << " ";
}
// 输出结果:1 2 3 4
return 0;
}
元素删除操作
forward_list的删除操作同样分为头部删除和指定位置之后删除两种场景。
头部删除
使用pop_front方法删除头部元素,时间复杂度O(1):
#include <forward_list>
#include <iostream>
int main() {
std::forward_list<int> fl = {1, 2, 3, 4};
// 删除头部元素
fl.pop_front();
for (int num : fl) {
std::cout << num << " ";
}
// 输出结果:2 3 4
return 0;
}
指定位置之后删除
使用erase_after方法删除指定迭代器之后的元素,也可以删除一段区间的元素:
#include <forward_list>
#include <iostream>
int main() {
std::forward_list<int> fl = {1, 2, 3, 4, 5};
auto it = fl.begin();
// 删除it之后的第一个元素,也就是2
fl.erase_after(it);
// 删除一段区间的元素,删除3和4
auto it2 = fl.begin();
auto it3 = fl.end();
// 先找到指向3的迭代器
++it2; // 现在it2指向3
// 找到指向5的迭代器
auto it4 = it2;
++it4; // it4指向5
++it4; // it4指向end
fl.erase_after(it2, it4);
for (int num : fl) {
std::cout << num << " ";
}
// 输出结果:1 5
return 0;
}
链表遍历与元素访问
forward_list不支持随机访问,不能通过下标获取元素,只能使用迭代器或者范围for循环进行顺序遍历。
#include <forward_list>
#include <iostream>
int main() {
std::forward_list<int> fl = {1, 2, 3, 4, 5};
// 范围for遍历
std::cout << "范围for遍历:";
for (int num : fl) {
std::cout << num << " ";
}
std::cout << std::endl;
// 迭代器遍历
std::cout << "迭代器遍历:";
for (auto it = fl.begin(); it != fl.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 访问第一个元素
if (!fl.empty()) {
std::cout << "第一个元素:" << fl.front() << std::endl;
}
return 0;
}
常用操作与算法适配
forward_list提供了一些常用的成员方法,同时也支持STL通用算法,以下是常见操作示例:
排序操作
forward_list有自己专属的sort成员方法,比通用sort算法效率更高:
#include <forward_list>
#include <iostream>
int main() {
std::forward_list<int> fl = {5, 2, 8, 1, 9};
// 升序排序
fl.sort();
for (int num : fl) {
std::cout << num << " ";
}
// 输出结果:1 2 5 8 9
return 0;
}
反转与去重
使用reverse方法反转链表,使用unique方法去除相邻的重复元素:
#include <forward_list>
#include <iostream>
int main() {
std::forward_list<int> fl = {1, 2, 2, 3, 3, 4};
// 去重相邻重复元素
fl.unique();
for (int num : fl) {
std::cout << num << " ";
}
// 输出结果:1 2 3 4
std::cout << std::endl;
// 反转链表
fl.reverse();
for (int num : fl) {
std::cout << num << " ";
}
// 输出结果:4 3 2 1
return 0;
}
拼接操作
使用splice_after方法可以将一个链表的元素拼接到另一个链表的指定位置之后:
#include <forward_list>
#include <iostream>
int main() {
std::forward_list<int> fl1 = {1, 4};
std::forward_list<int> fl2 = {2, 3};
// 将fl2的所有元素拼接到fl1的第一个元素之后
auto it = fl1.begin();
fl1.splice_after(it, fl2);
for (int num : fl1) {
std::cout << num << " ";
}
// 输出结果:1 2 3 4
return 0;
}
forward_list与list的区别
可以通过下表对比两种链表容器的特性,根据场景选择合适的容器:
| 特性 | forward_list | list |
|---|---|---|
| 链表方向 | 单向 | 双向 |
| 内存开销 | 更小,每个节点只有一个指针 | 更大,每个节点有两个指针 |
| 反向遍历 | 不支持 | 支持 |
| 尾部操作 | 无push_back、pop_back | 有push_back、pop_back |
| size方法 | 无 | 有 |
使用注意事项
- forward_list没有size方法,如果需要获取元素个数,需要自己遍历计数,时间复杂度O(n)。
- 插入删除操作都依赖迭代器,且只能操作指定位置之后的元素,使用时要注意迭代器的有效性,避免迭代器失效。
- 如果需要频繁反向遍历或者尾部操作,建议选择list而不是forward_list。
- forward_list的迭代器是单向前向迭代器,不支持--操作,只能++移动。
forward_list单向链表C++容器STL修改时间:2026-07-17 14:06:42