一、std::forward_list
(1) forward_list
与其适用场景
std::forward_list
是 C++的STL中的单向链表(Singly Linked List),它相比 std::list
(双向链表)更轻量,适用于仅需要单向遍历的场景。
主要特点:
- 单向链表:只能向前遍历,不支持双向迭代。
- 低内存开销:比
std::list
占用更少的内存(少一个指针)。 - 适合频繁插入和删除:由于其链表结构,插入和删除操作比
std::vector
高效(避免了数据移动)。 - 不支持随机访问:不像
std::vector
,无法使用operator[]
或at()
访问元素。
适用场景:
- 仅需单向遍历的数据结构
- 频繁头部插入/删除的场景(
push_front()
、pop_front()
高效),如队列、哈希链表、日志存储等。 - 内存敏感的应用(比
std::list
更节省空间)
头文件:
#include <forward_list>
(2) forward_list
vs list
特性 | forward_list |
list |
---|---|---|
结构 | 单向链表 | 双向链表 |
内存开销 | 较小(少一个指针) | 较大 |
遍历方向 | 只能向前 | 支持双向 |
访问效率 | O(n) 线性 | O(n) 线性 |
插入/删除 | O(1) 头部操作最优 | O(1) 任意位置操作 |
适用场景 | 轻量级、只需单向遍历的链表 | 需要双向遍历的场景 |
二、forward_list
的常用函数
函数 | 作用 |
---|---|
push_front(value) |
在头部插入元素 |
pop_front() |
移除头部元素 |
insert_after(it, value) |
在 it 之后插入 value |
erase_after(it) |
删除 it 之后的元素 |
remove(value) |
删除所有值等于 value 的元素 |
remove_if(pred) |
删除满足pred 条件的元素 |
front() |
返回链表头部元素 |
empty() |
判断链表是否为空 |
clear() |
清空所有元素 |
swap(other_list) |
交换两个链表的内容 |
sort() |
排序(仅支持升序) |
merge(other_list) |
合并两个有序列表 |
reverse() |
反转链表 |
unique() |
删除相邻的重复元素 |
注意:
std::forward_list
不提供返回其大小的函数。
三、forward_list
的基本使用
(1) 创建 forward_list
示例:
#include <iostream>
using namespace std;
#include <forward_list>
int main() {
forward_list<int> fl1 = { 1, 2, 3, 4, 5 }; // 列表初始化
forward_list<int> fl2(5, 10); // 5 个 10
for (int num : fl1)
{
cout << num << " ";
}
cout << endl;
for (int num : fl2)
{
cout << num << " ";
}
cout << endl;
system("pause");
return 0;
}
(2) 插入元素
示例:
#include <iostream>
using namespace std;
#include <forward_list>
int main() {
forward_list<int> fl = { 10, 20, 30 };
fl.push_front(5); // 在头部插入 5
auto it = fl.begin();
fl.insert_after(it, 15); // 在 10 之后插入 15
cout << "After insertions: ";
for (int num : fl)
{
cout << num << " ";
}
cout << endl;
system("pause");
return 0;
}
注意:
push_front()
(在链表头部插入元素)emplace_front()
(在头部插入元素,构造效率更高)insert_after()
(在指定位置后插入)emplace_after()
(在指定位置后插入)
(3) 删除元素
示例:
#include <iostream>
using namespace std;
#include <forward_list>
int main() {
forward_list<int> fl = {10, 20, 30, 40, 50};
fl.pop_front(); // 删除头部元素 10
fl.remove(30); // 删除所有值等于 30 的元素
cout << "After deletions: ";
for (int num : fl)
{
cout << num << " ";
}
cout << endl;
system("pause");
return 0;
}
(4) 反转、排序
示例:
#include <iostream>
using namespace std;
#include <forward_list>
int main() {
forward_list<int> fl = { 50, 10, 40, 30, 20 };
fl.sort(); // 排序
fl.reverse(); // 反转
cout << "Sorted and Reversed List: ";
for (int num : fl)
{
cout << num << " ";
}
cout << endl;
system("pause");
return 0;
}
注意:
sort()
默认为升序排列,再执行reverse()
后为逆序排列;
四、forward_list
的应用
(1)维护一个日志记录系统
要求:
- 每次新的日志添加到前面(头部插入)。
- 只保留最近
N
条日志。
示例:
#include <iostream>
using namespace std;
#include <forward_list>
#include <string>
#define MAX_LOGS 5 // 最大日志条数
class LogSystem {
forward_list<string> logs;
int size = 0;
public:
void addLog(const string& log)
{
logs.push_front(log); // 头部插入最新日志
if (++size > MAX_LOGS)
{
pop_back(); // 超过最大数量时删除最后一条
--size;
}
}
void pop_back()
{
if (logs.empty())
return;
auto it = logs.begin();
auto prev = logs.before_begin();
while (std::next(it) != logs.end()) // 找到倒数第二个元素
{
prev = it;
++it;
}
logs.erase_after(prev); // 删除最后一个元素
}
void showLogs()
{
cout << "Recent Logs:" << endl;
for (const auto& log : logs)
{
cout << log << endl;
}
}
};
int main() {
LogSystem logSys;
logSys.addLog("Log 1");
logSys.addLog("Log 2");
logSys.addLog("Log 3");
logSys.addLog("Log 4");
logSys.addLog("Log 5");
logSys.addLog("Log 6"); // 触发删除最早的 Log 1
logSys.showLogs();
system("pause");
return 0;
}
注意:
std::forward_list
不提供pop_back()函数,使用则需要自己编写相应的函数。