std::list 的基本用法

std::list 是一个双向链表容器,支持高效的插入和删除操作(尤其是在链表中间位置),但不支持随机访问。

一、基础用法

1. 头文件与命名空间

#include <list>        // 必须包含的头文件
using namespace std;   // 或显式使用 std::list

2. 定义与初始化

// 定义空 list
list<int> lst1;                          // 存储 int 类型的空链表

// 初始化为 n 个值为 val 的元素
list<int> lst2(5, 10);                   // 5 个元素,每个都是 10 → [10,10,10,10,10]

// 用初始化列表初始化(C++11+)
list<int> lst3 = {1, 2, 3, 4};           // 直接初始化元素 → [1,2,3,4]

// 复制另一个 list
list<int> lst4(lst3);                    // 复制 lst3 的内容 → [1,2,3,4]
list<int> lst5 = lst3;                   // 同上

二、常用成员函数

1. 元素访问(无随机访问,只能通过首尾或迭代器)

函数 功能说明 示例
front() 返回第一个元素的引用 int first = lst.front();
back() 返回最后一个元素的引用 int last = lst.back();

2. 容量与大小

函数 功能说明 示例
size() 返回当前元素个数 int len = lst.size();
empty() 判断容器是否为空 (size() == 0) if (lst.empty())
resize(n, val) 调整容器大小为 n,新增元素用 val 填充 lst.resize(5, 0); // 大小调整为 5

3. 元素修改(list 的核心优势:高效插入删除)

函数 功能说明 示例
push_back(val) 在尾部添加元素 lst.push_back(5);
pop_back() 删除尾部元素(不返回值) lst.pop_back();
push_front(val) 在头部添加元素(list 特有,vector 无) lst.push_front(0);
pop_front() 删除头部元素(list 特有) lst.pop_front();
insert(pos, val) 在迭代器 pos 位置插入 val(时间复杂度 O (1)) lst.insert(it, 10); //it 是迭代器
insert(pos, n, val) 在 pos 位置插入 n 个 val lst.insert(it, 3, 20);
erase(pos) 删除迭代器 pos 位置的元素 lst.erase(it);
erase(beg, end) 删除 [beg, end) 范围内的元素 lst.erase(beg, end);
clear() 清空所有元素(size() 变为 0) lst.clear();
swap(lst2) 与另一个 list 交换内容 lst.swap(lst2);
splice(pos, lst2) 将 lst2 的所有元素移动到 pos 位置(不复制,直接转移节点) lst.splice(it, lst2);

4. 迭代器(必须通过迭代器遍历,无下标访问)

函数 功能说明 示例
begin() / end() 正向迭代器(指向首元素 / 尾后位置) for (auto it = lst.begin(); it != lst.end(); ++it)
rbegin() / rend() 反向迭代器(指向尾元素 / 首前位置) for (auto it = lst.rbegin(); it != lst.rend(); ++it)

5. 其他常用函数

函数 功能说明 示例
sort() 对元素进行排序(默认升序) lst.sort();
sort(cmp) 自定义排序规则(传入比较函数) lst.sort(greater()); // 降序
reverse() 反转链表中的元素顺序 lst.reverse();
unique() 移除连续的重复元素(需先排序) lst.sort(); lst.unique();
merge(lst2) 合并两个已排序的链表(合并后仍有序) lst1.merge(lst2);

三、遍历 list 的方式(只能通过迭代器或范围 for)

list<int> lst = {1, 2, 3, 4, 5};

// 1. 正向迭代器遍历
for (list<int>::iterator it = lst.begin(); it != lst.end(); ++it) {
    cout << *it << " ";  // 输出:1 2 3 4 5
}

// 2. 反向迭代器遍历
for (list<int>::reverse_iterator it = lst.rbegin(); it != lst.rend(); ++it) {
    cout << *it << " ";  // 输出:5 4 3 2 1
}

// 3. 范围 for 循环(C++11+)
for (int x : lst) {
    cout << x << " ";  // 输出:1 2 3 4 5
}

四、list 与 vector 的核心区别

特性 std::list std::vector
数据结构 双向链表(节点存储数据,通过指针连接) 动态数组(连续内存空间)
随机访问 不支持([] 和 at() 不可用) 支持(O(1) 时间复杂度)
插入 / 删除(中间) 高效(O(1),只需修改指针) 低效(O(n),需移动后续元素)
插入 / 删除(首尾) 头部插入 O(1),尾部插入 O(1) 尾部插入 O(1)(可能扩容),头部插入 O(n)
内存连续性 不连续(节点分散存储) 连续(可直接访问底层数组)
迭代器稳定性 插入 / 删除元素后,其他迭代器仍有效 扩容后迭代器失效,删除中间元素后后续迭代器失效

示例:综合使用 list

#include <iostream>
#include <list>
#include <algorithm>  // 用于 greater 排序
using namespace std;

int main() {
    list<int> lst = {3, 1, 4, 2};
    
    // 在头部和尾部添加元素
    lst.push_front(0);    // → [0,3,1,4,2]
    lst.push_back(5);     // → [0,3,1,4,2,5]
    
    // 插入元素到中间(通过迭代器定位)
    auto it = lst.begin();
    advance(it, 2);  // 移动迭代器到索引2的位置(值为1)
    lst.insert(it, 100);  // → [0,3,100,1,4,2,5]
    
    // 排序(升序)
    lst.sort();  // → [0,1,2,3,4,5,100]
    
    // 反转
    lst.reverse();  // → [100,5,4,3,2,1,0]
    
    // 遍历输出
    cout << "元素: ";
    for (int x : lst) {
        cout << x << " ";  // 输出:100 5 4 3 2 1 0
    }
    
    // 删除第一个和最后一个元素
    lst.pop_front();  // → [5,4,3,2,1,0]
    lst.pop_back();   // → [5,4,3,2,1]
    
    cout << "\n最终大小: " << lst.size() << endl;  // 输出:5
    
    return 0;
}
posted @ 2025-09-04 01:18  开心猪扒  阅读(34)  评论(0)    收藏  举报