C++ std::list概念与使用案例

C++ std::list 概念详解

std::list 是 C++ 标准模板库(STL)中的一个双向链表容器。与 vectorarray 不同,它不保证元素在内存中连续存储,而是通过指针将各个元素连接起来。

核心特性

  1. 双向链表结构
    • 每个元素包含指向前驱和后继的指针
    • 支持双向遍历(前向和后向)
  2. 时间复杂度
    • 任意位置插入/删除:O(1)
    • 随机访问:O(n)(效率低)
    • 排序:O(n log n)(使用成员函数 sort()
  3. 内存特性
    • 非连续内存分配
    • 每个元素有额外指针开销(前驱 + 后继)
    • 不会导致迭代器失效(除被删除元素)
  4. 迭代器类型
    • 双向迭代器(支持 ++--
    • 不支持随机访问(不能 + n

常用成员函数

操作函数示例
插入元素push_back()list.push_back(10);
push_front()list.push_front(5);
insert()list.insert(it, 7);
删除元素pop_back()list.pop_back();
pop_front()list.pop_front();
erase()list.erase(it);
访问元素front()int first = list.front()
back()int last = list.back()
容量操作size()int len = list.size()
empty()if (list.empty()) ...
特殊操作splice()list1.splice(pos, list2)
sort()list.sort();
merge()list1.merge(list2);
reverse()list.reverse();

使用案例:订单管理系统

#include <iostream>
#include <list>
#include <string>
#include <algorithm>// 订单结构
struct Order {int id;std::string customer;double amount;Order(int i, std::string c, double a) : id(i), customer(c), amount(a) {}
};int main() {// 创建订单链表std::list<Order> orders;// 添加订单(三种方式)orders.push_back(Order(101, "Alice", 150.0));     // 尾部添加orders.emplace_back(102, "Bob", 99.99);           // 直接构造(C++11)orders.push_front(Order(100, "VIP", 500.0));      // 头部添加// 在特定位置插入auto it = orders.begin();std::advance(it, 2);  // 移动到第三个位置orders.insert(it, Order(103, "Charlie", 75.5));// 遍历并打印订单(C++11范围循环)std::cout << "All Orders:\n";for (const auto& order : orders) {std::cout << "ID: " << order.id << ", Customer: " << order.customer << ", Amount: $" << order.amount << "\n";}// 删除特定订单(金额<100)orders.remove_if([](const Order& o) {return o.amount < 100.0;});// 按金额升序排序orders.sort([](const Order& a, const Order& b) {return a.amount < b.amount;});// 新订单批次std::list<Order> newOrders = {{201, "David", 200.0},{202, "Eva", 350.0}};// 合并订单(到链表尾部)orders.splice(orders.end(), newOrders);// 遍历打印最终订单std::cout << "\nFinal Orders (Sorted & Merged):\n";for (const auto& order : orders) {std::cout << "ID: " << order.id << ", Customer: " << order.customer << ", Amount: $" << order.amount << "\n";}// 查找特定订单auto findIt = std::find_if(orders.begin(), orders.end(), [](const Order& o) { return o.customer == "Eva"; });if (findIt != orders.end()) {std::cout << "\nFound Eva's order: $" << findIt->amount << "\n";}return 0;
}
输出示例:
All Orders:
ID: 100, Customer: VIP, Amount: $500
ID: 101, Customer: Alice, Amount: $150
ID: 103, Customer: Charlie, Amount: $75.5
ID: 102, Customer: Bob, Amount: $99.99Final Orders (Sorted & Merged):
ID: 103, Customer: Charlie, Amount: $75.5
ID: 102, Customer: Bob, Amount: $99.99
ID: 101, Customer: Alice, Amount: $150
ID: 201, Customer: David, Amount: $200
ID: 202, Customer: Eva, Amount: $350
ID: 100, Customer: VIP, Amount: $500Found Eva's order: $350

关键操作详解

  1. 高效插入/删除

    // 在任意位置插入(O(1))
    auto it = orders.begin();
    std::advance(it, 3);
    orders.insert(it, Order(105, "Frank", 120.0));// 删除指定位置元素(O(1))
    orders.erase(it);
    
  2. 链表拼接

    // 将list2的所有元素移动到list1的指定位置
    list1.splice(position, list2);// 移动list2中的单个元素
    list1.splice(pos, list2, elementIt);// 移动list2中的元素范围
    list1.splice(pos, list2, startIt, endIt);
    
  3. 专用排序算法

    // 成员函数sort(比std::sort更高效)
    orders.sort(); // 默认使用operator<// 自定义排序
    orders.sort([](const Order& a, const Order& b) {return a.amount > b.amount; // 按金额降序
    });
    
  4. 链表合并

    // 合并两个有序链表
    list1.merge(list2); 
    // 注意:合并后list2为空
    

性能对比(vs vector)

操作std::liststd::vector
随机访问O(n)O(1)
头部插入/删除O(1)O(n)
尾部插入/删除O(1)O(1) 摊销
中间插入O(1)O(n)
内存连续性
内存开销高(指针)

最佳实践

  1. 适用场景

    • 需要频繁在任意位置插入/删除
    • 不需要随机访问
    • 需要稳定迭代器(不失效)
    • 需要高效合并/拆分操作
  2. 不适用场景

    • 需要随机访问元素
    • 内存受限环境
    • 需要缓存友好的操作
  3. 现代C++技巧

    // 结构化绑定(C++17)
    for (const auto& [id, customer, amount] : orders) {std::cout << customer << ": $" << amount << "\n";
    }// 自定义内存分配器
    std::list<int, MyAllocator> customList;
    

经典应用场景

  1. LRU缓存实现:使用链表+哈希表
  2. 撤销/重做功能:维护操作历史
  3. 消息队列系统:高效插入/删除
  4. 图算法:邻接表表示
  5. 多线程任务池:任务调度

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

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

相关文章

从0到1学Pandas(六):Pandas 与数据库交互

目录一、数据库基础操作1.1 连接数据库1.2 执行 SQL 查询1.3 创建与修改表结构二、数据导入导出2.1 从数据库读取数据2.2 将数据写入数据库2.3 大数据量处理三、数据库事务处理3.1 事务概念与实现3.2 批量数据更新3.3 错误处理与回滚四、数据库性能优化4.1 查询性能优化4.2 连接…

GitHub 趋势日报 (2025年07月26日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图602Qwen3-Coder573neko527hrms275BillionMail153Win11Debloat115hyperswitch57data…

机器人仿真(2)Ubuntu24.04下RTX5090配置IsaacSim与IsaacLab

目录 一、前言二、电脑配置三、配置步骤3.1 创建Conda环境3.2 安装PyTorch3.3 安装Isaac Sim3.4 安装Isaac Lab 四、总结 一、前言 博主自从去年开始就一直在关注Isaac Lab和Isaac Sim&#xff0c;但是一直以来由于手头设备只有4060&#xff0c;甚至没有达到最低配置16GB显存要…

DaVinci Resolve 19.0(达芬奇)软件安装包下载及详细安装教程|附带安装文件

[软件名称]&#xff1a;ArcGIS [软件大小]&#xff1a;2.99 GB [系统要求]&#xff1a;支持Win7及更高版本 [下载通道]: 迅雷网盘 [下载链接]:高速下载地址 https://pan.xunlei.com/s/VOW9nw-JV99A_7f_5hhpgqO2A1?pwdbufh# ⚠️:先用手机下载迅雷网盘保存到手机中&#xff0c…

Java学习第八十一部分——Shiro

目录 &#x1f4eb; 一、前言提要简介 &#x1f6e1;️ 二、核心功能介绍 ⚙️ 三、核心架构组件 ☕ 四、与Java的关系 ⚖️ 五、与Spring Security对比 &#x1f9e9; 六、典型应用场景 &#x1f48e; 七、总结归纳概述 &#x1f4eb; 一、前言提要简介 Apache Shiro 是…

虚拟机ubuntu20.04共享安装文件夹

ubuntu20.04共享安装文件夹 4.5 共享安装文件夹 将Windows存放安装文件的文件夹共享给虚拟机&#xff0c;如下图操作&#xff1a;如果是在ubuntu20.04中&#xff0c;还需要以下的操作&#xff1a; sudo mkdir /mnt/hgfs 此命令无效 sudo echo ‘vmhgfs-fuse /mnt/hgfs fu…

如何查看电脑后门IP和流量?

你是否也有以下经历&#xff1f;深夜&#xff0c;你的电脑风扇突然狂转&#xff0c;屏幕却一片寂静&#xff1b;每月流量莫名超标&#xff0c;账单高得离谱&#xff1b;鼠标偶尔不听使唤…这些可能不是电脑“闹脾气”&#xff0c;如何一探究竟&#xff1f; 想象一下&#xff1a…

分类预测 | MATLAB基于四种先进的优化策略改进蜣螂优化算法(IDBO)的SVM多分类预测

分类预测 | MATLAB基于四种先进的优化策略改进蜣螂优化算法(IDBO)的SVM多分类预测 目录分类预测 | MATLAB基于四种先进的优化策略改进蜣螂优化算法(IDBO)的SVM多分类预测分类效果基本介绍多策略量子自适应螺旋搜索算法研究摘要1. 引言1.1 研究背景1.2 研究意义1.3 研究目标2. 文…

Android 修改系统时间源码阅读

链接&#xff1a;XRefAndroid - Support Android 16.0 & OpenHarmony 5.0 (AndroidXRef/AospXRef) 这里看的Android 10的代码&#xff0c;选中Android 10&#xff0c;勾选所有工程&#xff0c;搜索DateTimeSettings‌&#xff1a; 看到showTimePicker应该是显示一个设置时…

关于自定义域和 GitHub Pages(Windows)

GitHub Pages 支持使用自定义域,或将站点 URL 的根目录从默认值(例如 )更改为您拥有的任何域,比如octocat.github.io。 谁可以使用此功能? GitHub Pages 在公共存储库中提供 GitHub Free 和 GitHub Free for organizations,在公共和私有存储库中提供 GitHub Pro、GitHub …

自动驾驶领域中的Python机器学习

数据预处理与特征工程 在自动驾驶系统中&#xff0c;数据是驱动决策的核心。从传感器&#xff08;如摄像头、激光雷达、毫米波雷达&#xff09;收集的原始数据通常包含噪声、缺失值和异常值&#xff0c;需要进行系统的预处理。Python的pandas库提供了强大的数据处理能力&#x…

PROFINET转CAN通讯协议转换速通汽车制造

在汽车系统领域之外&#xff0c;控制器局域网&#xff08;CAN&#xff09;总线技术亦广泛应用于多种工业环境。其固有的稳健性、可靠性与灵活性&#xff0c;使其成为工业自动化及控制系统中设备间通信的理想选择。CAN 总线技术在工业应用中的关键领域包括机器控制、传感器网络以…

影刀RPA_小红书笔记批量采集_源码解读

一、项目简介本项目是一个基于影刀RPA的小红书笔记批量采集工具&#xff0c;能够通过两种模式获取小红书平台的软文数据&#xff1a;搜索内容抓取和自定义链接抓取。工具使用Chrome浏览器自动化技术&#xff0c;实现了从网页数据采集、解析到Excel导出的完整流程。支持获取笔记…

以使命为帆,结业是重新出发的号角

站在私教班结业典礼的讲台上&#xff0c;望着眼前一张张闪烁着力量的面孔&#xff0c;我心中始终萦绕着一个信念&#xff1a;所有的相遇&#xff0c;都是为了共同奔赴一件更有意义的事。今天不是终点&#xff0c;而是 “使命的启程”—— 我们因不甘而相聚&#xff1a;不甘心行…

java测试题(下)

1. Spring 核心概念1.1 如何理解 Spring DI&#xff1f;DI&#xff08;依赖注入&#xff09; 是 IoC&#xff08;控制反转&#xff09; 的具体实现方式&#xff0c;由 Spring 容器在运行时通过以下方式自动注入依赖&#xff1a;构造器注入&#xff08;推荐&#xff09;Setter 注…

LC振荡Multisim仿真

电路图&#xff1a;说明&#xff1a;点击仿真后&#xff0c;先打开S1&#xff0c;可以看到C1的充电曲线。当电容充满电后&#xff0c;关闭S1&#xff0c;打开S2&#xff0c;这时候&#xff0c;C2电容会快速获得C1一半的电量。如果没有L&#xff0c;曲线会变得很陡。如果只加入电…

五、Web开发

文章目录1. SpringMVC自动配置概览2. 简单功能分析2.1 静态资源访问2.1.1 静态资源目录2.1.2 静态资源访问前缀2.1.3 webjar2.2 欢迎页支持2.3 自定义 Favicon2.4 静态资源配置原理2.4.1 配置类只有一个有参构造器2.4.2 资源处理的默认规则2.4.3 欢迎页的处理规则2.4.4 favicon…

Mysql 二进制安装常见问题

1. mysql: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory在centos9中升级了libncurses.so的版本为libncurses.so.6&#xff0c;所以找不到libncurses.so.5需要使用软连接指向libncurses.so.6ln -s /lib6…

OpenLayers 综合案例-点位聚合

看过的知识不等于学会。唯有用心总结、系统记录&#xff0c;并通过温故知新反复实践&#xff0c;才能真正掌握一二 作为一名摸爬滚打三年的前端开发&#xff0c;开源社区给了我饭碗&#xff0c;我也将所学的知识体系回馈给大家&#xff0c;助你少走弯路&#xff01; OpenLayers…

测试老鸟整理,物流项目系统测试+测试点分析(一)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 物流项目&#xf…