list容器简介及其接口函数

C++ list 容器详解

一、list 容器简介

list 是 C++ 标准模板库(STL)中的双向链表容器 ,定义在 <list> 头文件中。与 vector 不同,list 中的元素在内存中不连续存储,每个元素都包含指向前后元素的指针。

主要特点

特性 说明
存储方式 双向链表,非连续内存
插入/删除 O(1),任意位置高效操作
随机访问 不支持,需遍历
迭代器 双向迭代器(Bidirectional Iterator)
内存开销 较高(需存储指针)

二、list 的基本操作接口

接口函数速查表

类别 函数 时间复杂度
构造 list(), list(n,val), list(first,last) O(1)/O(n)
访问 front(), back() O(1)
迭代器 begin(), end(), rbegin(), rend() O(1)
容量 empty(), size(), max_size() O(1)
插入 push_front(), push_back(), insert(), emplace() O(1)/O(n)
删除 pop_front(), pop_back(), erase(), remove(), clear() O(1)/O(n)
修改 swap(), resize(), assign() O(1)/O(n)
特有 splice(), merge(), sort(), reverse(), unique() O(1)/O(n)

使用注意事项

注意事项 详细说明
迭代器稳定性 list 的插入/删除操作不会使其他元素的迭代器失效,只有被删除元素的迭代器会失效
内存开销 每个节点额外存储前后两个指针,内存占用比 vector 大
缓存友好性 非连续内存导致缓存命中率较低,遍历性能可能不如 vector
排序要求 merge()unique() 使用前需确保列表已排序,否则结果不确定
C++11 新特性 推荐使用 emplace_front()emplace_back()emplace() 系列函数进行原地构造,避免拷贝开销

2.1 构造函数

cpp 复制代码
std::list<int> lst1;                    // 空列表
std::list<int> lst2(5, 10);             // 5个元素,值为10
std::list<int> lst3(lst2);              // 拷贝构造
std::list<int> lst4(lst2.begin(), lst2.end());  // 范围构造
std::list<int> lst5 = {1, 2, 3, 4, 5};  // 初始化列表

2.2 元素访问

函数 函数声明 接口说明
front() reference front(); const_reference front() const; 返回 list 的第一个节点中值的引用
back() reference back(); const_reference back() const; 返回 list 的最后一个节点中值的引用
cpp 复制代码
std::list<int> lst = {1, 2, 3, 4, 5};

int first = lst.front();    // 1
int last = lst.back();      // 5

// 修改元素
lst.front() = 10;           // [10, 2, 3, 4, 5]
lst.back() = 50;            // [10, 2, 3, 4, 50]

注意:list 不支持 operator[] 和 at()

list 迭代器是双向迭代器,既不支持算术运算,也不支持 [] 运算符

2.3 容量函数

函数 函数声明 接口说明
empty() bool empty() const; 检测 list 是否为空,是返回 true,否则返回 false
size() size_type size() const; 返回 list 中有效节点的个数

2.4 插入删除函数

函数 函数声明 接口说明
push_front() void push_front(const value_type& val); void push_front(value_type&& val); 在 list 首元素前插入值为 val 的元素
pop_front() void pop_front(); 删除 list 中第一个元素
push_back() void push_back(const value_type& val); void push_back(value_type&& val); 在 list 尾部插入值为 val 的元素
pop_back() void pop_back(); 删除 list 中最后一个元素
insert() iterator insert(const_iterator pos, const value_type& val); 在 list position 位置中插入值为 val 的元素 ,返回指向第一个新插入元素的迭代器
erase() iterator erase(const_iterator pos); iterator erase(const_iterator first, const_iterator last); 删除 list position 位置的元素,返回被删除元素之后的下一个元素的迭代器
swap() void swap(list& x); 交换两个 list 中的元素
clear() void clear(); 清空 list 中的有效元素

三、迭代器

函数 返回值 说明
begin() 迭代器 指向首元素
end() 迭代器 指向尾元素之后
rbegin() 反向迭代器 指向尾元素
rend() 反向迭代器 指向首元素之前
cbegin() 常量迭代器 指向首元素 (C++11)
cend() 常量迭代器 指向尾元素之后 (C++11)
crbegin() 常量反向迭代器 指向尾元素 (C++11)
crend() 常量反向迭代器 指向首元素之前 (C++11)

迭代器使用示例

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

// ─────────────────────────────────────
// 1. 正向迭代器 (begin/end)
// ─────────────────────────────────────
for (auto it = lst.begin(); it != lst.end(); ++it) {
    std::cout << *it << " ";  // 输出: 1 2 3 4 5
}

// ─────────────────────────────────────
// 2. 反向迭代器 (rbegin/rend)
// ─────────────────────────────────────
for (auto rit = lst.rbegin(); rit != lst.rend(); ++rit) {
    std::cout << *rit << " ";  // 输出: 5 4 3 2 1
}

// ─────────────────────────────────────
// 3. 常量迭代器 (cbegin/cend) - 只读
// ─────────────────────────────────────
for (auto it = lst.cbegin(); it != lst.cend(); ++it) {
    // *it = 10;  // ❌ 错误:不能修改
    std::cout << *it << " ";  // 输出: 1 2 3 4 5
}

// ─────────────────────────────────────
// 4. 常量反向迭代器 (crbegin/crend) - 只读
// ─────────────────────────────────────
for (auto rit = lst.crbegin(); rit != lst.crend(); ++rit) {
    // *rit = 10;  // ❌ 错误:不能修改
    std::cout << *rit << " ";  // 输出: 5 4 3 2 1
}

// ─────────────────────────────────────
// 5. 范围 for 循环 (C++11) - 推荐
// ─────────────────────────────────────
for (const auto& elem : lst) {
    std::cout << elem << " ";  // 输出: 1 2 3 4 5
}

vector 与 list 对比表

对比项 vector list
底层结构 动态顺序表,一段连续空间 带头结点的双向循环链表
随机访问 支持随机访问,访问某个元素效率 O(1) 不支持随机访问,访问某个元素效率 O(N)
插入和删除 任意位置插入和删除效率低,需要搬移元素,时间复杂度为 O(N) 插入时有可能需要增容:开辟新空间,拷贝元素,释放旧空间,导致效率更低 任意位置插入和删除效率高,不需要搬移元素,时间复杂度为 O(1)
空间利用率 底层为连续空间,不容易造成内存碎片,空间利用率高,缓存利用率高 底层节点动态开辟,小节点容易造成内存碎片,空间利用率低,缓存利用率低
迭代器 原生态指针 对原生态指针 (节点指针) 进行封装
迭代器失效 插入元素时,要给所有的迭代器重新赋值,因为插入元素有可能会导致重新扩容,致使原来迭代器失效 删除时,当前迭代器需要重新赋值否则会失效 插入元素不会导致迭代器失效 删除元素时,只会导致当前迭代器失效,其他迭代器不受影响
使用场景 需要高效存储,支持随机访问,不关心插入删除效率 大量插入和删除操作,不关心随机访问
相关推荐
adore.9682 小时前
2.22 oj基础92 93 94+U12
数据结构·c++·算法
Rhystt2 小时前
代码随想录第二十六天|669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树
数据结构·c++·算法·leetcode
想做功的洛伦兹力12 小时前
2026/2/22日打卡
数据结构·算法
A懿轩A3 小时前
【Java 基础编程】Java 集合框架详解:List/Set/Map 选型 + ArrayList/HashMap 原理与使用
java·windows·list
不染尘.3 小时前
字符串哈希
开发语言·数据结构·c++·算法·哈希算法
今儿敲了吗3 小时前
25| 丢手绢
数据结构·c++·笔记·学习·算法
wostcdk3 小时前
归并排序 & 逆序对
数据结构·算法
手握风云-4 小时前
Java 数据结构第三十期:LRUCache 的“遗忘机制”
数据结构
重生之后端学习4 小时前
17. 电话号码的字母组合
java·开发语言·数据结构·算法·深度优先