必须包含头文件,声明空链表为std::list lst;支持初值列表初始化和范围构造,但不支持size+value构造;仅能用迭代器增删查改,不可用下标访问。
std::list
直接用 std::list 前必须包含头文件 ,它不支持随机访问,也不提供 operator[]。常见错误是当成 std::vector 用,比如写 my_list[0] —— 这会编译失败。
std::list lst;
std::list<:string> names = {"Alice", "Bob", "Charlie"};
std::list lst(other_vec.begin(), other_vec.end());
std::list lst(10, 42); 这种“大小+默认值”方式初始化(那是 vector 的语法)std::list 是双向链表,所有增删都在常数时间完成,但前提是用对接口。误用 push_back() 或 erase() 的迭代器版本以外的方式,容易导致逻辑错乱或性能退化。
lst.push_front(10);
lst.push_back("hello");
it 之前):lst.insert(it, 99);
lst.erase(it);(it 必须合法且未失效)lst.remove_if([](int x) { return x % 2 == 0; });
lst.erase(2); —— erase() 没有接受整数索引的重载,这行不通因为没有 operator[] 和 at(),任何试图“取第 n 个元素”的操作都得靠移动迭代器,时间复杂度是 O(n)。别为了图方便写循环 + std::next(it, n) 来模拟下标——那说明你可能该换容器了。
for (auto it = lst.begin(); it != lst.end(); ++it) {
std::cout << *it << "\n";
}for (const auto& x : lst) {
std::cout << x << "\n";
}for (auto rit = lst.rbegin(); rit != lst.rend(); ++rit) {
std::cout << *rit << "\n";
}lst.front() / lst.back(),但务必确保非空,否则未定义行为这些成员函数不复制元素,只调整指针,是 list 相比其他序列容器的核心价值。尤其 splice() 可以零成本转移节点,常被用于实现任务队列、LRU 缓存等场景。
lst1.splice(lst1.end(), lst2);(执行后 lst2 为空)
接某一段:lst1.splice(lst1.begin(), lst2, it1, it2);(左闭右开区间)lst1.merge(lst2);(lst2 会被清空)lst.sort();(支持自定义比较:lst.sort(std::greater()); )sort() 和 merge() 要求元素可比较;splice() 不调用拷贝/移动构造,所以对不可拷贝类型(如 std::unique_ptr)也安全std::list,关键是放弃“按位置操作”的思维惯性。它的优势不在索引,而在稳定迭代器、高效局部增删、以及零拷贝的节点重组能力。一旦开始频繁调用 std::advance 或手写循环找第 N 个元素,就该重新评估是否选错了容器。