深入解析C++ STL List:双向链表的特性与高级操作

news2025/7/5 19:58:24

一、引言

在C++ STL容器家族中,list作为双向链表容器,具有独特的性能特征。本文将通过完整代码示例,深入剖析链表的核心操作,揭示其底层实现机制,并对比其他容器的适用场景。文章包含4000余字详细解析,适合需要高效数据操作的开发者阅读。

https://example.com/list-structure.png

二、环境准备

  • 编译器:支持C++11及以上标准
  • 开发环境:Visual Studio/CLion/Code::Blocks
  • 关键头文件:#include <list>
  • 命名空间:using namespace std;

三、完整代码示例

cpp

#include <iostream>
#include <list>
using namespace std;

#define arr_size 10

int main() {
    list<int> arr;
    for (int i = 0; i < arr_size; i++) {
        arr.push_back(i + 1);
    }
    list<int> mine_arr = { 1, 4, 6, 7 };

    arr.push_back(11); // 链表末尾添加值11
    arr.push_front(0); // 链表头部添加值0

    int size = arr.size(); // 链表的元素个数

    auto it = arr.begin();
    arr.insert(it, -1); // 在链表的指定位置插入值

    arr.pop_back();  // 删除链表尾部的值
    arr.pop_front(); // 删除链表头部的值

    it = arr.begin(); // 重新获取迭代器
    arr.erase(it);    // 删除链表指定位置的元素

    bool if_not = arr.empty(); // 链表判空操作,若为空则返回true

    arr.sort(); // 按字典序排序链表中的元素
    arr.merge(mine_arr); // 合并 mine_arr 到 arr

    // 遍历链表并输出
    for (auto it = arr.begin(); it != arr.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

四、核心操作解析

4.1 容器初始化

cpp

list<int> arr;                // 创建空双向链表
for (int i=0; i<arr_size; i++) {
    arr.push_back(i+1);       // 尾部插入元素1~10
}

​链表特性​​:

  • 每个节点包含前驱/后继指针
  • 内存非连续分配,插入删除无需内存迁移
  • 初始化状态:[1,2,3,4,5,6,7,8,9,10]

4.2 元素操作对比

操作vector时间复杂度list时间复杂度特点说明
push_backO(1)摊销O(1)尾部插入高效
push_frontO(n)O(1)头部插入无需元素移动
insertO(n)O(1)指定位置插入常数时间
eraseO(n)O(1)删除元素不引起内存拷贝

4.3 关键操作详解

cpp

arr.push_back(11);    // 尾部添加11 → [1,2,...,10,11]
arr.push_front(0);    // 头部插入0 → [0,1,2,...,11]

auto it = arr.begin();
arr.insert(it, -1);   // 在首元素前插入-1 → [-1,0,1,...,11]

arr.pop_back();       // 删除尾部11 → [-1,0,1,...,10]
arr.pop_front();      // 删除头部-1 → [0,1,2,...,10]

it = arr.begin();
arr.erase(it);        // 删除首元素0 → [1,2,3,...,10]

​迭代器特性​​:

  • 插入/删除操作不会使其他迭代器失效(被删除元素的迭代器除外)
  • erase()返回下一个有效迭代器

五、高级操作实践

5.1 排序与合并

cpp

arr.sort();           // 原地排序 → [1,2,3,...,10]
arr.merge(mine_arr);  // 合并有序链表 → [1,1,2,3,4,4,6,7,10]

​合并特性​​:

  • 要求两个链表都已排序
  • 合并后mine_arr变为空链表
  • 时间复杂度O(n+m)

5.2 splice高效转移

cpp

list<int> temp = {100, 200};
arr.splice(arr.begin(), temp);  // 转移temp所有元素到arr头部

​优势​​:

  • 零拷贝操作,时间复杂度O(1)
  • 不会影响原容器迭代器

六、迭代器深度剖析

6.1 迭代器类型

cpp

auto it = arr.begin();    // 双向迭代器(支持++/--)
auto rend = arr.rend();   // 反向迭代器(指向尾部之前的元素)

​操作支持​​:

  • ++/-- 前进/后退
  • * 解引用
  • ==/!= 比较

6.2 迭代器失效场景

cpp

// 正确操作
auto it = arr.insert(arr.begin(), 99);
arr.erase(it);  // 直接删除插入的元素

// 危险操作
auto it = arr.begin();
arr.push_front(88);
arr.erase(it);  // 未定义行为(迭代器可能失效)

​安全准则​​:

  • 插入操作不会使现有迭代器失效
  • 删除操作会使被删元素的迭代器失效

七、性能优化策略

7.1 预分配节点空间

cpp

list<int> arr;
arr.reserve(arr_size);  // 预分配节点(非容量概念)

​实现原理​​:

  • 提前分配节点内存池
  • 减少动态内存分配次数

7.2 splice代替拷贝

cpp

list<int> source = {1,2,3};
list<int> target;
target.splice(target.end(), source);  // 转移元素而非复制

​性能对比​​:

  • splice:O(1)时间,零拷贝
  • insert:O(n)时间,需复制元素

八、常见陷阱与解决方案

8.1 合并后的容器状态

cpp

list<int> a = {1,2}, b = {3,4};
a.merge(b);  // a变为[1,2,3,4],b变为空

​注意​​:合并后原容器需要重新初始化

8.2 迭代器跨越end()

cpp

auto it = arr.end();
--it;  // 合法,指向最后一个元素
++it;  // 合法,回到end()

​危险操作​​:

cpp

++(--arr.end());  // 可能越界

九、与其他容器的对比

特性listvectordeque
内存布局非连续连续分段连续
头部插入/删除O(1)O(n)O(1)
随机访问不支持O(1)O(1)
迭代器失效仅被删元素批量失效批量失效
适用场景频繁插入删除随机访问需求头尾高效操作

十、实战应用场景

  1. ​任务调度器​​:频繁的添加/删除任务场景
  2. ​撤销重做实现​​:需要维护操作历史记录
  3. ​内存池管理​​:高效管理非连续内存块
  4. ​大数据排序​​:外部排序的分块处理

十一、总结与展望

本文通过完整代码示例,系统讲解了list的核心特性:

  • 双向链表结构带来的高效插入删除
  • 迭代器的稳定性优势
  • 与其他容器的适用场景对比

​选择建议​​:

  • 需要频繁在两端操作 → 优先考虑deque
  • 需要随机访问 → 选择vector
  • 需要大量中间插入删除 → list是最佳选择

​扩展学习​​:

  1. 研究list的底层节点分配策略
  2. 实现自定义的链表容器
  3. 对比不同STL容器的迭代器实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2340542.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Self-Ask:LLM Agent架构的思考模式 | 智能体推理框架与工具调用实践

作为程序员&#xff0c;我们习惯将复杂问题分解为可管理的子任务&#xff0c;这正是递归和分治算法的核心思想。那么&#xff0c;如何让AI模型也具备这种结构化思考能力&#xff1f;本文深入剖析Self-Ask推理模式的工作原理、实现方法与最佳实践&#xff0c;帮助你构建具有清晰…

安装 vmtools

第2章 安装 vmtools 1.安装 vmtools 的准备工作 1&#xff09;现在查看是否安装了 gcc ​ 查看是否安装gcc 打开终端 输入 gcc - v 安装 gcc 链接&#xff1a;https://blog.csdn.net/qq_45316173/article/details/122018354?ops_request_misc&request_id&biz_id10…

【论文阅读20】-CNN-Attention-BiGRU-滑坡预测(2025-03)

这篇论文主要探讨了基于深度学习的滑坡位移预测模型&#xff0c;结合了MT-InSAR&#xff08;多时相合成孔径雷达干涉测量&#xff09;观测数据&#xff0c;提出了一种具有可解释性的滑坡位移预测方法。 [1] Zhou C, Ye M, Xia Z, et al. An interpretable attention-based deep…

滑动窗口学习

2090. 半径为 k 的子数组平均值 题目 问题分析 给定一个数组 nums 和一个整数 k&#xff0c;需要构建一个新的数组 avgs&#xff0c;其中 avgs[i] 表示以 nums[i] 为中心且半径为 k 的子数组的平均值。如果在 i 前或后不足 k 个元素&#xff0c;则 avgs[i] 的值为 -1。 思路…

# 基于PyTorch的食品图像分类系统:从训练到部署全流程指南

基于PyTorch的食品图像分类系统&#xff1a;从训练到部署全流程指南 本文将详细介绍如何使用PyTorch框架构建一个完整的食品图像分类系统&#xff0c;涵盖数据预处理、模型构建、训练优化以及模型保存与加载的全过程。 1. 系统概述 本系统实现了一个基于卷积神经网络(CNN)的…

v-html 显示富文本内容

返回数据格式&#xff1a; 只有图片名称 显示不出完整路径 解决方法&#xff1a;在接收数据后手动给img格式的拼接vite.config中的服务器地址 页面&#xff1a; <el-button click"">获取信息<el-button><!-- 弹出层 --> <el-dialog v-model&…

【数学建模】孤立森林算法:异常检测的高效利器

孤立森林算法&#xff1a;异常检测的高效利器 文章目录 孤立森林算法&#xff1a;异常检测的高效利器1 引言2 孤立森林算法原理2.1 核心思想2.2 算法流程步骤一&#xff1a;构建孤立树(iTree)步骤二&#xff1a;构建孤立森林(iForest)步骤三&#xff1a;计算异常分数 3 代码实现…

<项目代码>YOLO小船识别<目标检测>

项目代码下载链接 YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0…

Crawl4AI:打破数据孤岛,开启大语言模型的实时智能新时代

当大语言模型遇见数据饥渴症 在人工智能的竞技场上&#xff0c;大语言模型&#xff08;LLMs&#xff09;正以惊人的速度进化&#xff0c;但其认知能力的跃升始终面临一个根本性挑战——如何持续获取新鲜、结构化、高相关性的数据。传统数据供给方式如同输血式营养支持&#xff…

【Spring Boot】MyBatis多表查询的操作:注解和XML实现SQL语句

1.准备工作 1.1创建数据库 &#xff08;1&#xff09;创建数据库&#xff1a; CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;&#xff08;2&#xff09;使用数据库 -- 使⽤数据数据 USE mybatis_test;1.2 创建用户表和实体类 创建用户表 -- 创建表[⽤⼾表…

[Android]豆包爱学v4.5.0小学到研究生 题目Ai解析

拍照解析答案 【应用名称】豆包爱学 【应用版本】4.5.0 【软件大小】95mb 【适用平台】安卓 【应用简介】豆包爱学&#xff0c;一般又称河马爱学教育平台app,河马爱学。 关于学习&#xff0c;你可能也需要一个“豆包爱学”这样的AI伙伴&#xff0c;它将为你提供全方位的学习帮助…

Qt开发:软件崩溃时,如何生成dump文件

文章目录 一、程序崩溃时如何自动生成 Dump 文件二、支持多线程中的异常捕获三、在 DLL 中使用 Dump 捕获四、封装成可复用类五、MiniDumpWriteDump函数详解 一、程序崩溃时如何自动生成 Dump 文件 步骤一&#xff1a;包含必要的头文件 #include <Windows.h> #include …

普罗米修斯Prometheus监控安装(mac)

普罗米修斯是后端数据监控平台&#xff0c;通过Node_exporter/mysql_exporter等收集数据&#xff0c;Grafana将数据用图形的方式展示出来 官网各平台下载 Prometheus安装&#xff08;mac&#xff09; &#xff08;1&#xff09;通过brew安装 brew install prometheus &…

Python SQL 工具包:SQLAlchemy介绍

SQLAlchemy 是一个功能强大且灵活的 Python SQL 工具包和对象关系映射&#xff08;ORM&#xff09;库。它被广泛用于与关系型数据库进行交互&#xff0c;提供了从低级 SQL 表达式到高级 ORM 的完整工具链。SQLAlchemy 的设计目标是让开发者能够以 Pythonic 的方式操作数据库&am…

Shader属性讲解+Cg语言讲解

CPU调用GPU传递数据 修改Render组件的material属性 在脚本中更改游戏物体材质颜色代码示例&#xff1a; using System.Collections; using System.Collections.Generic; using UnityEngine;public class TestFixedColor : MonoBehaviour {void Start(){//创建预制体GameObjec…

基于LightGBM-TPE算法对交通事故严重程度的分析与可视化

基于LightGBM-TPE算法对交通事故严重程度的分析与可视化 原文&#xff1a; Analysis and visualization of accidents severity based on LightGBM-TPE 1. 引言部分 文章开篇强调了道路交通事故作为意外死亡的主要原因&#xff0c;引起了多学科领域的关注。分析事故严重性特…

什么是CRM系统,它的作用是什么?CRM全面指南

CRM&#xff08;Customer Relationship Management&#xff0c;客户关系管理&#xff09;系统是一种专门用于集中管理客户信息、优化销售流程、提升客户满意度、支持精准营销、驱动数据分析决策、加强跨部门协同、提升客户生命周期价值的业务系统工具。其中&#xff0c;优化销售…

MYSQL之库的操作

创建数据库 语法很简单, 主要是看看选项(与编码相关的): CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] ...] create_specification: [DEFAULT] CHARACTER SET charset_name [DEFAULT] COLLATE collation_name 1. 语句中大写的是…

Linux 下的网络管理(附加详细实验案例)

一、简单了解 NM&#xff08;NetworkManager&#xff09; 在 Linux 中&#xff0c;NM 是 NetworkManager 的缩写。它是一个用于管理网络连接的守护进程和工具集。 在 RHEL9 上&#xff0c;使用 NM 进行网络配置&#xff0c;ifcfg &#xff08;也称为文件&#xff09;将不再…

基于SpringBoot的疫情居家检测管理系统(源码+数据库)

514基于SpringBoot的疫情居家检测管理系统&#xff0c;系统包含三种角色&#xff1a;管理员、用户、医生&#xff0c;主要功能如下。 【用户功能】 1. 首页&#xff1a;获取系统信息。 2. 论坛&#xff1a;参与居民讨论和分享信息。 3. 公告&#xff1a;查看社区发布的各类公告…