序列式容器 - list

一、list 的核心特性

list 是一个双向链表 (doubly linked list),这是它区别于vector(动态数组)的核心:

  • 底层结构:每个元素都有前驱和后继指针,元素在内存中不连续存储
  • 优势:任意位置的插入 / 删除操作效率极高(O (1)),无需移动其他元素
  • 劣势:不支持随机访问(无法用下标[]访问),只能通过迭代器遍历,访问元素效率低(O (n))
  • 额外开销:每个元素需要存储前驱 / 后继指针,内存开销比vector

二、list 的基本用法(完整代码示例)

cpp

运行

复制代码
#include <iostream>
#include <list>   // 必须包含list头文件
#include <algorithm>  // 用于sort、find等算法
using namespace std;

int main() {
    // 1. 创建list容器
    list<int> myList;  // 空的int类型list
    list<int> list2(5, 10);  // 初始化5个元素,每个值为10
    list<int> list3 = {1, 3, 5, 2, 4};  // 初始化列表(C++11及以上)

    // 2. 插入元素(list的核心优势:任意位置高效插入)
    myList.push_back(10);  // 尾部插入
    myList.push_front(20); // 头部插入
    // 在指定位置插入(需先获取迭代器)
    auto it = myList.begin();  // 指向第一个元素(20)的迭代器
    myList.insert(++it, 30);   // 在20和10之间插入30,此时list:20 → 30 → 10

    // 3. 访问元素(不支持[]和at,只能用迭代器/front/back)
    cout << "第一个元素:" << myList.front() << endl;  // 20
    cout << "最后一个元素:" << myList.back() << endl; // 10

    // 4. 遍历list(三种常见方式)
    cout << "\n方式1:迭代器遍历:";
    for (list<int>::iterator it = myList.begin(); it != myList.end(); ++it) {
        cout << *it << " ";
    }
    cout << "\n方式2:范围for遍历:";
    for (int num : myList) {
        cout << num << " ";
    }
    cout << "\n方式3:反向遍历:";
    for (list<int>::reverse_iterator it = myList.rbegin(); it != myList.rend(); ++it) {
        cout << *it << " ";
    }

    // 5. 删除元素(同样支持任意位置高效删除)
    myList.pop_front();  // 删除头部元素(20)
    myList.pop_back();   // 删除尾部元素(10)
    cout << "\n删除头尾后:";
    for (int num : myList) cout << num << " "; // 只剩30

    // 6. list专属操作(区别于其他容器)
    list3.sort();  // 链表自带排序(vector用std::sort,list不能用)
    cout << "\n排序后的list3:";
    for (int num : list3) cout << num << " "; // 1 2 3 4 5

    list3.remove(3);  // 删除所有值为3的元素
    cout << "\n删除值为3后:";
    for (int num : list3) cout << num << " "; // 1 2 4 5

    list3.unique();   // 删除连续重复元素(需先排序才会生效)
    myList.clear();   // 清空容器
    cout << "\n清空后是否为空:" << (myList.empty() ? "是" : "否") << endl;

    return 0;
}

输出结果

plaintext

复制代码
第一个元素:20
最后一个元素:10

方式1:迭代器遍历:20 30 10 
方式2:范围for遍历:20 30 10 
方式3:反向遍历:10 30 20 
删除头尾后:30 
排序后的list3:1 2 3 4 5 
删除值为3后:1 2 4 5 
清空后是否为空:是

三、list 的关键注意事项

  1. 迭代器特性

    • list 的迭代器是双向迭代器 (只能 ++/--),不是随机访问迭代器,因此:
      • 不能用it + 5这种随机跳转操作,只能++it逐步移动
      • 不能直接用std::sort排序,必须用list.sort()成员函数
  2. 插入 / 删除不失效迭代器

    • 对 list 插入 / 删除元素时,除了指向被删除元素的迭代器,其他迭代器都不会失效(vector 插入可能导致迭代器全部失效)
  3. 常用成员函数

    函数 作用
    sort() 对链表元素升序排序
    remove(val) 删除所有值为 val 的元素
    unique() 删除连续重复的元素
    reverse() 反转链表元素顺序
    splice() 拼接两个 list(高效移动)

四、list vs vector 选型对比

场景 选 vector 选 list
随机访问(按下标取值)
尾部增删元素
中间 / 头部频繁增删元素
内存连续性(需兼容 C 数组)
内存开销(少指针)

总结

  1. list是双向链表结构,核心优势是任意位置的插入 / 删除操作效率极高 ,核心劣势是不支持随机访问
  2. list有专属的操作函数(如sort()remove()),不能直接使用std::sort等依赖随机访问迭代器的算法。
  3. 选型时,若业务场景以 "中间 / 头部频繁增删" 为主,选list;若以 "随机访问、尾部增删" 为主,选vector
相关推荐
AI人工智能+电脑小能手几秒前
【大白话说Java面试题】【Java基础篇】第20题:HashMap在计算index的时候,为什么要对数组长度做减1操作
java·开发语言·数据结构·后端·面试·哈希算法·hash-index
祖国的好青年5 分钟前
VS Code 搭建 React Native 开发环境(Windows 实战指南)
android·windows·react native·react.js
牢姐与蒯5 分钟前
cpp数据结构之map
数据结构
故事和你9119 分钟前
洛谷-算法2-3-分治与倍增5
开发语言·数据结构·c++·算法·动态规划·图论
love530love31 分钟前
Python 3.12 解决 MediaPipe “no attribute ‘solutions‘” 终极方案:基于全版本硬核实测的避坑指南
开发语言·人工智能·windows·python·comfyui·mediapipe·solutions
北顾笙98036 分钟前
day37-数据结构力扣
数据结构·算法·leetcode
YJlio1 小时前
Windows Internals 读书笔记 10.3.3:Task Scheduler 架构详解
人工智能·windows·笔记·python·学习·chatgpt·架构
liuyao_xianhui2 小时前
进程概念与进程状态_Linux
linux·运维·服务器·数据结构·c++·哈希算法·宽度优先
如君愿2 小时前
考研复习 Day 26 | 习题--计算机网络第三章(数据链路层 下)、数据结构 多维数组与广义表
数据结构·计算机网络·考研·记录考研
bqq198610262 小时前
MySQL分库分表
数据结构·mysql