C++中std::list的使用详解和综合实战代码示例
std::list
是 C++ STL(标准模板库)中提供的一个 双向链表容器,适用于需要频繁在中间或头尾插入/删除元素的场景。
一、std::list 概述
#include
-
定义:
std::list<int> myList;
-
底层结构:双向链表
-
特点:
- 插入/删除效率高(O(1))
- 不能随机访问(没有
[]
操作符,不能用索引) - 每个节点存储数据 + 前后指针
二、常见用法示例
1. 创建与初始化
std::list<int> list1; // 空列表std::list<int> list2 = {1, 2, 3, 4}; // 列表初始化std::list<int> list3(5, 10); // 5 个值为 10 的元素
2. 插入与删除
std::list<int> myList = {1, 2, 3};// 头尾插入myList.push_front(0); // -> 0 1 2 3myList.push_back(4); // -> 0 1 2 3 4// 头尾删除myList.pop_front(); // -> 1 2 3 4myList.pop_back(); // -> 1 2 3// 插入到指定位置(使用 iterator)auto it = myList.begin();std::advance(it, 1); // 移动到第2个元素myList.insert(it, 10); // -> 1 10 2 3// 删除指定位置it = myList.begin();std::advance(it, 2);myList.erase(it); // -> 1 10 3
3. 遍历 list
for (auto it = myList.begin(); it != myList.end(); ++it) std::cout << *it << \" \";for (const auto& val : myList) std::cout << val << \" \";
4. 其他常用操作
myList.clear(); // 清空myList.empty(); // 是否为空myList.size(); // 元素个数myList.front(); // 第一个元素myList.back(); // 最后一个元素
三、特殊操作
1. 去重(相邻元素)
std::list<int> lst = {1, 1, 2, 2, 3, 3};lst.unique(); // -> 1 2 3
2. 排序
lst.sort(); // 升序排序lst.sort(std::greater<int>()); // 降序排序
3. 反转
lst.reverse();
四、自定义类型示例
struct Person { std::string name; int age;};std::list<Person> people = { {\"Alice\", 30}, {\"Bob\", 25}, {\"Charlie\", 35}};people.sort([](const Person& a, const Person& b) { return a.age < b.age;});
五、使用场景总结
vector
更合适)六、高级应用示例
下面是 std::list
的高级用法示范,涵盖:
- 自定义排序与
splice
- 使用
remove_if
删除特定条件元素 merge
合并已排序链表- 使用
unique
去重 - 自定义类型支持
std::list
示例1:高级用法综合示范
#include #include #include #include struct Person { std::string name; int age; // 支持排序的比较函数 bool operator<(const Person& other) const { return age < other.age; } // 支持去重的等价比较函数 bool operator==(const Person& other) const { return name == other.name && age == other.age; }};void PrintList(const std::list<Person>& lst, const std::string& title) { std::cout << title << \":\\n\"; for (const auto& p : lst) { std::cout << \" \" << p.name << \", age \" << p.age << \"\\n\"; } std::cout << std::endl;}int main() { std::list<Person> group1 = { {\"Alice\", 30}, {\"Bob\", 25}, {\"Charlie\", 28} }; std::list<Person> group2 = { {\"Diana\", 26}, {\"Eve\", 24}, {\"Bob\", 25} }; PrintList(group1, \"Group 1\"); PrintList(group2, \"Group 2\"); // sort + merge(合并两个已排序 list) group1.sort(); // 按 age 升序排序 group2.sort(); group1.merge(group2); // group2 被清空 PrintList(group1, \"Merged Group\"); // unique 去重(需要 operator==) group1.unique(); PrintList(group1, \"After unique (去重)\"); // remove_if:删除年龄小于 28 的成员 group1.remove_if([](const Person& p) { return p.age < 28; }); PrintList(group1, \"After remove_if (age < 28)\"); // splice:将一个 list 插入另一个位置 std::list<Person> newcomers = { {\"Frank\", 31}, {\"Grace\", 29} }; auto it = std::next(group1.begin()); group1.splice(it, newcomers); // 插入 newcomers 到 group1 中间 PrintList(group1, \"After splice newcomers\"); return 0;}
输出:
Group 1: Alice, age 30 Bob, age 25 Charlie, age 28Group 2: Diana, age 26 Eve, age 24 Bob, age 25Merged Group: Eve, age 24 Bob, age 25 Bob, age 25 Diana, age 26 Charlie, age 28 Alice, age 30After unique (去重): Eve, age 24 Bob, age 25 Diana, age 26 Charlie, age 28 Alice, age 30After remove_if (age < 28): Charlie, age 28 Alice, age 30After splice newcomers: Charlie, age 28 Frank, age 31 Grace, age 29 Alice, age 30
小结:std::list
高级用法速查
list.sort()
list.merge()
list.unique()
==
)remove_if()
splice()
<
与 ==
示例2:实现简易任务调度系统
示例支持功能:
- 添加任务(支持优先级)
- 动态执行并删除任务
- 删除过期任务
- 支持按优先级排序执行
Task 定义:
#include #include #include #include #include #include using Clock = std::chrono::steady_clock;struct Task { std::string name; int priority; // 数字越大,优先级越高 Clock::time_point expireTime; std::function<void()> action; bool operator<(const Task& other) const { return priority > other.priority; // 用于 sort:高优先级在前 }};
TaskScheduler 类:
class TaskScheduler {private: std::list<Task> tasks;public: void AddTask(const Task& task) { tasks.push_back(task); } void RemoveExpiredTasks() { auto now = Clock::now(); tasks.remove_if([&](const Task& task) { return now > task.expireTime; }); } void RunTopTask() { if (tasks.empty()) return; // 优先级排序(高优先级排前面) tasks.sort(); auto task = tasks.front(); tasks.pop_front(); std::cout << \"[Running] \" << task.name << std::endl; task.action(); } void RunAllTasks() { tasks.sort(); for (const auto& task : tasks) { std::cout << \"[Running] \" << task.name << std::endl; task.action(); } tasks.clear(); } void PrintTasks() const { std::cout << \"Scheduled Tasks:\\n\"; for (const auto& task : tasks) { std::cout << \" \" << task.name << \" (priority: \" << task.priority << \")\\n\"; } }};
使用示例
int main() { TaskScheduler scheduler; scheduler.AddTask({ \"TaskA\", 1, Clock::now() + std::chrono::seconds(10), [] { std::cout << \" -> Running TaskA\\n\"; } }); scheduler.AddTask({ \"TaskB\", 5, Clock::now() + std::chrono::seconds(5), [] { std::cout << \" -> Running TaskB\\n\"; } }); scheduler.AddTask({ \"TaskC\", 3, Clock::now() + std::chrono::seconds(1), [] { std::cout << \" -> Running TaskC\\n\"; } }); std::cout << \"All tasks:\\n\"; scheduler.PrintTasks(); std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟延时 scheduler.RemoveExpiredTasks(); std::cout << \"\\nTasks after removing expired:\\n\"; scheduler.PrintTasks(); std::cout << \"\\nExecuting tasks...\\n\"; scheduler.RunAllTasks();}
输出示例
All tasks:Scheduled Tasks: TaskA (priority: 1) TaskB (priority: 5) TaskC (priority: 3)Tasks after removing expired:Scheduled Tasks: TaskA (priority: 1) TaskB (priority: 5)Executing tasks...[Running] TaskB -> Running TaskB[Running] TaskA -> Running TaskA
优势
std::list
支持 任意位置插入/删除,无需重新分配内存。- 适合构建 实时任务队列、异步处理池、调度表系统。
- 支持
splice()
快速合并多个任务队列,零开销。