C++中std::list的使用详解和综合实战代码示例

std::list 是 C++ STL(标准模板库)中提供的一个 双向链表容器,适用于需要频繁在中间或头尾插入/删除元素的场景。


一、std::list 概述

cpp 复制代码
#include <list>
  • 定义

    cpp 复制代码
    std::list<int> myList;
  • 底层结构:双向链表

  • 特点

    • 插入/删除效率高(O(1))
    • 不能随机访问(没有 [] 操作符,不能用索引)
    • 每个节点存储数据 + 前后指针

二、常见用法示例

1. 创建与初始化

cpp 复制代码
std::list<int> list1;                           // 空列表
std::list<int> list2 = {1, 2, 3, 4};            // 列表初始化
std::list<int> list3(5, 10);                    // 5 个值为 10 的元素

2. 插入与删除

cpp 复制代码
std::list<int> myList = {1, 2, 3};

// 头尾插入
myList.push_front(0);  // -> 0 1 2 3
myList.push_back(4);   // -> 0 1 2 3 4

// 头尾删除
myList.pop_front();    // -> 1 2 3 4
myList.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

cpp 复制代码
for (auto it = myList.begin(); it != myList.end(); ++it)
    std::cout << *it << " ";

for (const auto& val : myList)
    std::cout << val << " ";

4. 其他常用操作

cpp 复制代码
myList.clear();              // 清空
myList.empty();              // 是否为空
myList.size();               // 元素个数
myList.front();              // 第一个元素
myList.back();               // 最后一个元素

三、特殊操作

1. 去重(相邻元素)

cpp 复制代码
std::list<int> lst = {1, 1, 2, 2, 3, 3};
lst.unique();  // -> 1 2 3

2. 排序

cpp 复制代码
lst.sort();     // 升序排序
lst.sort(std::greater<int>());  // 降序排序

3. 反转

cpp 复制代码
lst.reverse();

四、自定义类型示例

cpp 复制代码
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;
});

五、使用场景总结

需求 是否适合 std::list
快速在中间插入/删除 ✅ 非常适合
随机访问元素 ❌ 不适合(用 vector 更合适)
大量头部插入
需要排序和去重
多线程场景 ⚠️ 需要加锁(非线程安全)

六、高级应用示例

下面是 std::list高级用法示范,涵盖:

  • 自定义排序与 splice
  • 使用 remove_if 删除特定条件元素
  • merge 合并已排序链表
  • 使用 unique 去重
  • 自定义类型支持 std::list

示例1:高级用法综合示范

cpp 复制代码
#include <iostream>
#include <list>
#include <algorithm>
#include <string>

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 28

Group 2:
  Diana, age 26
  Eve, age 24
  Bob, age 25

Merged Group:
  Eve, age 24
  Bob, age 25
  Bob, age 25
  Diana, age 26
  Charlie, age 28
  Alice, age 30

After unique (去重):
  Eve, age 24
  Bob, age 25
  Diana, age 26
  Charlie, age 28
  Alice, age 30

After remove_if (age < 28):
  Charlie, age 28
  Alice, age 30

After splice newcomers:
  Charlie, age 28
  Frank, age 31
  Grace, age 29
  Alice, age 30

小结:std::list 高级用法速查

功能 函数 说明
排序 list.sort() 内部比较或自定义排序
合并 list.merge() 需先排序,合并后自动排序
去重 list.unique() 删除相邻重复元素(需支持 ==
条件删除 remove_if() 按 lambda 或谓词删除
插入链表 splice() 整段迁移插入,不拷贝、零成本
自定义类型支持 重载 <== 支持排序、去重、自定义谓词

示例2:实现简易任务调度系统

示例支持功能:

  • 添加任务(支持优先级)
  • 动态执行并删除任务
  • 删除过期任务
  • 支持按优先级排序执行

Task 定义:

cpp 复制代码
#include <iostream>
#include <list>
#include <string>
#include <chrono>
#include <functional>
#include <algorithm>

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 类:

cpp 复制代码
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";
        }
    }
};

使用示例

cpp 复制代码
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() 快速合并多个任务队列,零开销。

小结

操作 时间复杂度
插入/删除(任意位置) O(1)(已知 iterator)
访问第 n 个元素 O(n)
遍历所有元素 O(n)

相关推荐
滴水成川19 分钟前
现代 C++ 开发工作流(VSCode / Cursor)
开发语言·c++·vscode·cursor
张同学的IT技术日记24 分钟前
重构 MVC:让经典架构完美适配复杂智能系统的后端业务逻辑层(内附框架示例代码)
c++·后端·重构·架构·mvc·软件开发·工程应用
万能的小裴同学29 分钟前
星痕共鸣数据分析2
c++·数据分析
圆头猫爹1 小时前
洛谷刷题7.24
数据结构·算法
HY小海1 小时前
【数据结构】八大排序
数据结构
刚入坑的新人编程1 小时前
暑期算法训练.8
数据结构·c++·算法·面试·哈希算法
TalkU浩克2 小时前
C++中使用Essentia实现STFT/ISTFT
开发语言·c++·音频·istft·stft·essentia
少许极端2 小时前
数据结构3-单双链表的泛型实现及ArrayList与LinkedList的区别
java·数据结构·linkedlist·顺序表与链表区别
UP_Continue2 小时前
算法讲解--有效三角形的个数
数据结构
小比卡丘2 小时前
【C++进阶】第7课—红黑树
java·开发语言·c++