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;
}
相关推荐
ooseabiscuit1 小时前
PHP与C++:Web与系统编程的终极对决
前端·c++·php
艾莉丝努力练剑2 小时前
【Linux网络】Linux 网络编程:应用层自定义协议与序列化(3):网络计算器实现和守护进程
linux·运维·服务器·网络·c++·计算机网络·安全
Severus_black2 小时前
【初阶数据结构】链式二叉树(BinaryTreeNode)与递归
c语言·数据结构·链表
千寻girling2 小时前
周日那天参加的力扣周赛... —— 10号
java·javascript·c++·python·算法·leetcode·职场和发展
研究点啥好呢2 小时前
dji机器人SLAM算法工程师 面试题精选:10道高频考题+答案解析
c++·算法·机器人·slam·dji
jllllyuz2 小时前
VC++ 读写 Excel 文件实现
开发语言·c++·excel
小小编程能手2 小时前
C++文件从操作:
开发语言·c++
茉莉玫瑰花茶2 小时前
C++ 17 详细特性解析(6)
开发语言·c++
东方.既白2 小时前
QML与C++炫酷界面交互DEMO
开发语言·c++·交互