STL容器——list类

一、list是什么

list官方文档

在数组中,数据在逻辑空间和物理空间上都是连续的。

而链表中的数据在逻辑上时连续的在物理空间上不是连续的。所以可以更好的利用空间,但是不能随机访问。

访问时只能访问下一个,就是单向链表 ,可以访问上一个和下一个,就是双向链表

STL的list就是:C 语言里的双向链表,被 C++ 封装好了,你不用自己写结构体、不用自己管理指针,直接拿来用就行。


二、list的特点

1. 任意位置插入 / 删除元素效率极高(O (1))

vector在插入或删除元素时,需要移动后面所有元素,效率是 O(n);

list 是双向链表,只需要修改节点的指针指向,不移动任何元素,无论在头部、中间、尾部操作,时间复杂度都是固定的 O(1)。

2. 高效的链表拼接(splice)

list 提供 splice() 函数,可以把另一个 list 的节点直接拼接到当前 list

时间复杂度 O(1),不拷贝、不移动任何元素,仅修改指针;

vector 做类似操作必须拷贝数据,效率较慢。

3. 内存分配灵活,无空间浪费

vector 是连续内存,会预分配多余空间,存在内存浪费;

list 每个元素独立分配节点内存,用多少分配多少,没有冗余空间;

不会因为扩容导致大量内存拷贝。

4.不支持随机访问

不能用 \[\] 或 .at() 直接访问第 k 个元素,只能从头 / 尾遍历,查找慢(O (n));

5.内存占用大

每个节点都要存储前后指针,内存占用比 vector 高;

6.遍历速度略慢

节点不连续,遍历速度慢于 vector。


三、list的使用

3.1 list的初始化

名称 使用示例 功能说明
default(默认构造) list<int> lst1; 创建一个空链表,无任何元素
fill(填充构造) list<int> lst2(5, 10); 5 个元素,每个都是 10
range(迭代器初始化) list<int> lst4(src.begin() + 1, src.end() - 1) 用 [first, last) 区间元素构造
copy(拷贝构造) list<int> lst5(lst2); 复制 lst2

这里和之前学习的容器很统一,因为他们都是顺序容器。

使用示例

在使用时要使用"#include<list>"头文件

cpp 复制代码
#include <iostream>
#include <list>
using namespace std;

void print(const list<int>& lst) {
    for (int x : lst) cout << x << " ";
    cout << endl;
}

int main() {
    // 1. 默认构造:空链表
    list<int> lst1;
    cout << "1. 默认构造: ";
    print(lst1);

    // 2. 填充构造:5个10
    list<int> lst2(5, 10);
    cout << "2. 填充构造: ";
    print(lst2);

    // 3. 迭代器区间构造
    list<int> src = {1,2,3,4,5};
    list<int> lst3(src.begin(), src.end());
    cout << "3. 迭代器构造: ";
    print(lst3);

    // 4. 拷贝构造
    list<int> lst4(lst2);
    cout << "4. 拷贝构造: ";
    print(lst4);

    return 0;
}

3.2 list类对象的容量操作

| 名称 | 使用示例 | 功能说明 |
| size | lst.size() | 获取list中实际存储的元素个数 |

empty lst.empty() 检测list是否为空,为空返回true,否则返回false

使用示例

cpp 复制代码
#include <iostream>
#include <list>
using namespace std;

int main()
{
    list<int> v1;

    cout << "是否为空:" << boolalpha << v1.empty() << endl;
    cout << "元素个数:" << v1.size() << endl;

    v1.push_back(1);
    v1.push_back(2);

    cout << "是否为空:" << boolalpha << v1.empty() << endl;
    cout << "元素个数:" << v1.size() << endl;

    return 0;
}

3.3 list类对象的访问及遍历操作

名称 使用示例 功能说明
begin() end() s.begin() s.end () begin() 获取指向第一个元素的迭代器;end() 获取指向最后一个元素下一个位置的迭代器
rbegin() rend() s.rbegin () s.rend () rbegin() 获取指向最后一个元素的反向迭代器;rend() 获取指向第一个元素前一个位置的反向迭代器
范围 for(C++11) for (char ch : s) {cout << ch;} 更简洁的遍历方式,底层等价于迭代器遍历
front() lst.front() 返回 list 第一个元素的引用
back() lst.back() 返回 list 最后一个元素的引用

这里少了\[\]访问。

使用示例

cpp 复制代码
#include <iostream>
#include <list>
using namespace std;

int main() {
    list<int> lst = {10, 20, 30};

    // 1. begin() + end() 正向遍历
    cout << "正向遍历:";
    for (auto it = lst.begin(); it != lst.end(); ++it)
        cout << *it << " ";
    cout << endl;

    // 2. rbegin() + rend() 反向遍历
    cout << "反向遍历:";
    for (auto it = lst.rbegin(); it != lst.rend(); ++it)
        cout << *it << " ";
    cout << endl;

    // 3. 范围for(最简单)
    cout << "范围for:";
    for (int x : lst)
        cout << x << " ";
    cout << endl;

    // 4. front() 第一个元素
    cout << "第一个元素:" << lst.front() << endl;

    // 5. back() 最后一个元素
    cout << "最后一个元素:" << lst.back() << endl;

    return 0;
}

3.4 list类对象的修改操作

| 名称 | 使用示例 | 功能说明 |
| push_front(val) | | 在 list 首元素前插入值为 val 的元素 |
| pop_front() | | 删除 list 中第一个元素 |
| push_back(val) | | 在 list 尾部插入值为 val 的元素 |
| pop_back() | | 删除 list 中最后一个元素 |
| insert(pos, val) | | 在迭代器 pos 指向的位置前插入值为 val 的元素 |
| erase(pos) | | 删除迭代器 pos 指向的元素 |
| swap(other) | | 交换两个 list 的内容 |

clear() 清空 list 中的所有有效元素

使用示例

cpp 复制代码
#include <iostream>
#include <list>
using namespace std;

int main() {
    list<int> l;

    // 1. 头尾添加
    l.push_back(10);      // 容器:[10]
    l.push_front(20);     // 容器:[20, 10]
    l.push_back(30);      // 容器:[20, 10, 30]

    // 2. insert 插入
    auto it = l.begin();
    l.insert(++it, 50);   // 在20后面插入50 → [20, 50, 10, 30]

    // 3. 删除头尾
    l.pop_front();        // 删除第一个20 → [50, 10, 30]
    l.pop_back();         // 删除最后30 → [50, 10]

    // 4. erase 删除指定位置
    l.erase(l.begin());   // 删除第一个50 → [10]

    // 5. clear 清空
    l.clear();            // 清空 → 元素个数:0

    // 6. swap 交换两个list
    list<int> l1 = {1,2};
    list<int> l2 = {3,4};
    l1.swap(l2);          // l1变成[3,4],l2变成[1,2]

    return 0;
}
相关推荐
2601_9561219710 小时前
二分算法(知识点+题目)
c++·算法
蒙奇·D·路飞-12 小时前
OpenClaw:开源的《合金弹头》精神续作与终极本地部署指南
c++·开源·mfc
小星星闪亮登场13 小时前
2026萌新联赛第三场-- (郑州轻工业大学)
数据结构·c++·经验分享·算法·贪心算法·排序算法·深度优先
梓䈑14 小时前
【用 Vibe Coding 实现的 C++17 在线判题系统】前端开发 + Web 自动化测试
前端·c++·ai编程
冻柠檬飞冰走茶14 小时前
PTA基础编程题目集 7-8超速判断(C++语言实现)
开发语言·数据结构·c++·算法
TunerT_TQ15 小时前
Valhalla 静态工程审阅 #018|MMCV 源码证据驱动评测【大厂开源基础设施特辑】
c++·开源·mfc·#计算机视觉·#商汤科技·#openmmlab·#静态源码审计
别动我齐刘海15 小时前
Day6 unitree_G1人形机器人GMR—— MotionInput
c语言·c++·人工智能·学习·机器学习·机器人·github
Henry Zhu12316 小时前
C++17 `weak_from_this` 详解:让对象安全地观察自己
c++
June`19 小时前
warp shuffle指令
c++·人工智能·算法·cuda
乱七八糟的屋子19 小时前
【C++数值计算】NumCpp超详细入门教程(纯正Numpy语法、零学习成本、C++首选科学计算库、性能压测对比)
c++·数值计算·numpy·高性能计算·科学计算·ndarray