深入解析C++ STL List:双向链表的特性与高级操作
一、引言
在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 10int 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); // 链表末尾添加值11arr.push_front(0); // 链表头部添加值0int 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(); // 链表判空操作,若为空则返回truearr.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_back | O(1)摊销 | O(1) | 尾部插入高效 |
| push_front | O(n) | O(1) | 头部插入无需元素移动 |
| insert | O(n) | O(1) | 指定位置插入常数时间 |
| erase | O(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()); // 可能越界
九、与其他容器的对比
| 特性 | list | vector | deque |
|---|---|---|---|
| 内存布局 | 非连续 | 连续 | 分段连续 |
| 头部插入/删除 | O(1) | O(n) | O(1) |
| 随机访问 | 不支持 | O(1) | O(1) |
| 迭代器失效 | 仅被删元素 | 批量失效 | 批量失效 |
| 适用场景 | 频繁插入删除 | 随机访问需求 | 头尾高效操作 |
十、实战应用场景
- 任务调度器:频繁的添加/删除任务场景
- 撤销重做实现:需要维护操作历史记录
- 内存池管理:高效管理非连续内存块
- 大数据排序:外部排序的分块处理
十一、总结与展望
本文通过完整代码示例,系统讲解了list的核心特性:
- 双向链表结构带来的高效插入删除
- 迭代器的稳定性优势
- 与其他容器的适用场景对比
选择建议:
- 需要频繁在两端操作 → 优先考虑deque
- 需要随机访问 → 选择vector
- 需要大量中间插入删除 → list是最佳选择
扩展学习:
- 研究list的底层节点分配策略
- 实现自定义的链表容器
- 对比不同STL容器的迭代器实现
相关文章:
深入解析C++ STL List:双向链表的特性与高级操作
一、引言 在C STL容器家族中,list作为双向链表容器,具有独特的性能特征。本文将通过完整代码示例,深入剖析链表的核心操作,揭示其底层实现机制,并对比其他容器的适用场景。文章包含4000余字详细解析,适合需…...
Uniapp:pages.json页面路由
目录 一、pages二、style 一、pages uni-app 通过 pages 节点配置应用由哪些页面组成,pages 节点接收一个数组,数组每个项都是一个对象,其属性值如下: 属性类型默认值描述pathString配置页面路径styleObject配置页面窗口表现nee…...
Self-Ask:LLM Agent架构的思考模式 | 智能体推理框架与工具调用实践
作为程序员,我们习惯将复杂问题分解为可管理的子任务,这正是递归和分治算法的核心思想。那么,如何让AI模型也具备这种结构化思考能力?本文深入剖析Self-Ask推理模式的工作原理、实现方法与最佳实践,帮助你构建具有清晰…...
【前端】【业务场景】【面试】在网页开发中,如何优化图片以提高页面加载速度?解决不同设备屏幕适配问题
📌 问题 1:在网页开发中,如何优化图片以提高页面加载速度? 🔍 一、关键词总结 关键词说明图片压缩借助 TinyPNG、ImageOptim 等工具,无损减小图片文件大小格式选择JPEG(照片类)、P…...
Git Flow分支模型
经典分支模型(Git Flow) 由 Vincent Driessen 提出的 Git Flow 模型,是管理 main(或 master)和 dev 分支的经典方案: main 用于生产发布,保持稳定; dev 用于日常开发,合并功能分支(feature/*); 功能开发在 feature 分支进行,完成后合并回 dev; 预发布分支(rele…...
安装 vmtools
第2章 安装 vmtools 1.安装 vmtools 的准备工作 1)现在查看是否安装了 gcc 查看是否安装gcc 打开终端 输入 gcc - v 安装 gcc 链接:https://blog.csdn.net/qq_45316173/article/details/122018354?ops_request_misc&request_id&biz_id10…...
【论文阅读20】-CNN-Attention-BiGRU-滑坡预测(2025-03)
这篇论文主要探讨了基于深度学习的滑坡位移预测模型,结合了MT-InSAR(多时相合成孔径雷达干涉测量)观测数据,提出了一种具有可解释性的滑坡位移预测方法。 [1] Zhou C, Ye M, Xia Z, et al. An interpretable attention-based deep…...
滑动窗口学习
2090. 半径为 k 的子数组平均值 题目 问题分析 给定一个数组 nums 和一个整数 k,需要构建一个新的数组 avgs,其中 avgs[i] 表示以 nums[i] 为中心且半径为 k 的子数组的平均值。如果在 i 前或后不足 k 个元素,则 avgs[i] 的值为 -1。 思路…...
用户需求报告、系统需求规格说明书、软件需求规格说明的对比分析
用户需求报告、系统需求规格说明书(SyRS)和软件需求规格说明书(SRS)是需求工程中的关键文档,分别对应不同层次和视角的需求描述。以下是它们的核心区别对比: 1. 用户需求报告(User Requirem…...
# 基于PyTorch的食品图像分类系统:从训练到部署全流程指南
基于PyTorch的食品图像分类系统:从训练到部署全流程指南 本文将详细介绍如何使用PyTorch框架构建一个完整的食品图像分类系统,涵盖数据预处理、模型构建、训练优化以及模型保存与加载的全过程。 1. 系统概述 本系统实现了一个基于卷积神经网络(CNN)的…...
v-html 显示富文本内容
返回数据格式: 只有图片名称 显示不出完整路径 解决方法:在接收数据后手动给img格式的拼接vite.config中的服务器地址 页面: <el-button click"">获取信息<el-button><!-- 弹出层 --> <el-dialog v-model&…...
【数学建模】孤立森林算法:异常检测的高效利器
孤立森林算法:异常检测的高效利器 文章目录 孤立森林算法:异常检测的高效利器1 引言2 孤立森林算法原理2.1 核心思想2.2 算法流程步骤一:构建孤立树(iTree)步骤二:构建孤立森林(iForest)步骤三:计算异常分数 3 代码实现…...
<项目代码>YOLO小船识别<目标检测>
项目代码下载链接 YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN)࿰…...
Crawl4AI:打破数据孤岛,开启大语言模型的实时智能新时代
当大语言模型遇见数据饥渴症 在人工智能的竞技场上,大语言模型(LLMs)正以惊人的速度进化,但其认知能力的跃升始终面临一个根本性挑战——如何持续获取新鲜、结构化、高相关性的数据。传统数据供给方式如同输血式营养支持ÿ…...
AI 技术发展:从起源到未来的深度剖析
一、AI 的起源与早期发展 人工智能(AI)作为计算机科学的重要分支,其诞生可以追溯到 20 世纪中叶。1943 年,艾伦・图灵提出图灵机的概念,为计算机科学和 AI 理论奠定了基础。1950 年,图灵又提出著名的图灵…...
jsconfig.json文件的作用
jsconfig.json文件的作用 为什么今天会谈到这个呢?有这么一个场景:我们每次开发项目时都会给路径配置别名,配完别名之后可以简化我们的开发,但是随之而来的就有一个问题,一般来说,当我们使用相对路径时…...
nodejs的包管理工具介绍,npm的介绍和安装,npm的初始化包 ,搜索包,下载安装包
nodejs的包管理工具介绍,npm的介绍和安装,npm的初始化包 ,搜索包,下载安装包 🧰 一、Node.js 的包管理工具有哪些? 工具简介是否默认特点npmNode.js 官方的包管理工具(Node Package Manager&am…...
常见的raid有哪些,使用场景是什么?
RAID(Redundant Array of Independent Disks,独立磁盘冗余阵列)是一种将多个物理硬盘组合成一个逻辑硬盘的技术,目的是通过数据冗余和/或并行访问提高性能、容错能力和存储容量。不同的 RAID 级别有不同的实现方式和应用场景。以下…...
【Spring Boot】MyBatis多表查询的操作:注解和XML实现SQL语句
1.准备工作 1.1创建数据库 (1)创建数据库: CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;(2)使用数据库 -- 使⽤数据数据 USE mybatis_test;1.2 创建用户表和实体类 创建用户表 -- 创建表[⽤⼾表…...
金融数据分析(Python)个人学习笔记(12):网络爬虫
一、导入模块和函数 from bs4 import BeautifulSoup from urllib.request import urlopen import re from urllib.error import HTTPError from time import timebs4:用于解析HTML和XML文档的Python库。 BeautifulSoup:方便地从网页内容中提取和处理数据…...
[Android]豆包爱学v4.5.0小学到研究生 题目Ai解析
拍照解析答案 【应用名称】豆包爱学 【应用版本】4.5.0 【软件大小】95mb 【适用平台】安卓 【应用简介】豆包爱学,一般又称河马爱学教育平台app,河马爱学。 关于学习,你可能也需要一个“豆包爱学”这样的AI伙伴,它将为你提供全方位的学习帮助…...
Qt开发:软件崩溃时,如何生成dump文件
文章目录 一、程序崩溃时如何自动生成 Dump 文件二、支持多线程中的异常捕获三、在 DLL 中使用 Dump 捕获四、封装成可复用类五、MiniDumpWriteDump函数详解 一、程序崩溃时如何自动生成 Dump 文件 步骤一:包含必要的头文件 #include <Windows.h> #include …...
普罗米修斯Prometheus监控安装(mac)
普罗米修斯是后端数据监控平台,通过Node_exporter/mysql_exporter等收集数据,Grafana将数据用图形的方式展示出来 官网各平台下载 Prometheus安装(mac) (1)通过brew安装 brew install prometheus &…...
Python SQL 工具包:SQLAlchemy介绍
SQLAlchemy 是一个功能强大且灵活的 Python SQL 工具包和对象关系映射(ORM)库。它被广泛用于与关系型数据库进行交互,提供了从低级 SQL 表达式到高级 ORM 的完整工具链。SQLAlchemy 的设计目标是让开发者能够以 Pythonic 的方式操作数据库&am…...
Shader属性讲解+Cg语言讲解
CPU调用GPU传递数据 修改Render组件的material属性 在脚本中更改游戏物体材质颜色代码示例: using System.Collections; using System.Collections.Generic; using UnityEngine;public class TestFixedColor : MonoBehaviour {void Start(){//创建预制体GameObjec…...
基于LightGBM-TPE算法对交通事故严重程度的分析与可视化
基于LightGBM-TPE算法对交通事故严重程度的分析与可视化 原文: Analysis and visualization of accidents severity based on LightGBM-TPE 1. 引言部分 文章开篇强调了道路交通事故作为意外死亡的主要原因,引起了多学科领域的关注。分析事故严重性特…...
什么是CRM系统,它的作用是什么?CRM全面指南
CRM(Customer Relationship Management,客户关系管理)系统是一种专门用于集中管理客户信息、优化销售流程、提升客户满意度、支持精准营销、驱动数据分析决策、加强跨部门协同、提升客户生命周期价值的业务系统工具。其中,优化销售…...
MySQL 启动报错:InnoDB 表空间丢失问题及解决方法
MySQL 启动报错:InnoDB 表空间丢失问题及解决方法 在启动 MySQL 时,遇到了如下错误: 2025-01-16T12:43:28.341240Z 0 [ERROR] InnoDB: Tablespace 5975 was not found at ./my_jspt/sw_rtu_message_202408.ibd. 2025-01-16T12:43:28.341244…...
MYSQL之库的操作
创建数据库 语法很简单, 主要是看看选项(与编码相关的): CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] ...] create_specification: [DEFAULT] CHARACTER SET charset_name [DEFAULT] COLLATE collation_name 1. 语句中大写的是…...
笔记本电脑研发笔记:BIOS,Driver,Preloader详记
在笔记本电脑的研发过程中,Driver(驱动程序)、BIOS(基本输入输出系统)和 Preloader(预加载程序)之间存在着密切的相互关系和影响,具体如下: 相互关系 BIOS 与 Preload…...
