C++ STL:list和vector的比较

底层数据结构

Vector: 底层实现为动态数组,提供了一段连续的内存空间。这种连续存储使得 vector 能够提供快速的随机访问能力。

随机访问(通过索引访问元素)的时间复杂度为 O(1)。

因为可能涉及内存重新分配和数据移动,所以在尾部插入和删除操作的平均时间复杂度接近 O(1)。

因为可能需要移动后续或前面的元素,所以在中间或开始进行插入或删除操作的时间复杂度为 O(n)。

List: 底层实现为双向链表,由分散的内存块通过指针链接而成,使其在插入和删除操作上更加高效,但牺牲了随机访问的性能。

因为需要从头部或尾部遍历,随机访问的时间复杂度为 O(n)。

因为只需要修改指针,而不涉及元素的移动,插入和删除操作的时间复杂度接近 O(1)。

容量管理

Vector: 当当前容量不足以容纳新元素时,vector 会自动增加其容量(通常是加倍),这涉及到现有元素的复制和移动到新的内存地址。

List: 每次插入或删除操作只涉及局部内存分配或释放,不需要整体移动其他元素。

   由于 vector 的连续内存特性,可能会导致更大的内存预留(容量)以减少重新分配的频率,而 list 的内存使用更为紧凑,但每个元素需要额外的空间来存储前后节点的地址。

迭代器支持

Vector: 支持随机访问迭代器,可以进行 +、-、<、> 等操作。

List: 仅支持双向迭代器,不支持随机访问操作,但支持 ++ 和 -- 来前后移动。

  list不能使用普通指针作为迭代器,因为它需要特殊的迭代器来正确地遍历链表,包括进行递增、递减、取值等操作​​。它提供的迭代器是双向迭代器(Bidirectional Iterators),允许前移和后移操作​​。

 vector中,插入操作可能会导致容器重新分配内存,这会使所有现有迭代器、引用和指针失效。list的插入和删除操作不会使除了“指向被操作元素”的迭代器之外的任何迭代器失效。即使是删除操作,也只有指向被删除元素的迭代器会失效,其他迭代器仍然有效​​。

#include <iostream>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4};// 插入前的迭代器auto it = vec.begin() + 2;std::cout << "Before insertion: " << *it << std::endl; // 输出: 3// 插入元素导致容量可能改变vec.insert(vec.begin() + 1, 99);// 尝试访问原迭代器(未定义行为,因为迭代器可能失效)// std::cout << "After insertion: " << *it << std::endl; // 未定义行为// 正确的做法是重新获取迭代器it = vec.begin() + 3;std::cout << "After insertion: " << *it << std::endl; // 输出: 3return 0;
}

缓存友好性

vector 由于其连续的内存布局,通常提供更好的缓存一致性和性能。

CPU 缓存是一种非常快速的内存,位于 CPU 和主内存(RAM)之间,用于减少从主内存访问数据的延迟。当程序访问内存中的数据时,它会尝试先从缓存中获取数据,因为从缓存读取数据比从主内存读取要快得多。

由于 vector 使用一段连续的内存空间来存储数据,这意味着当你访问 vector 中的一个元素时,相邻的元素很可能已经被预加载到 CPU 缓存中。这是因为 CPU 通常会预加载你访问的内存地址附近的数据,这个过程称为预取。当你遍历一个 vector 并访问它的元素时,由于数据连续存储,许多元素访问操作可能直接从缓存中进行,而不是从更慢的主内存中。这种特性使得 vector 在执行连续内存访问操作时,如遍历或顺序访问元素,具有很高的性能。

相比之下,list 使用的是非连续存储,即它的元素分布在内存的不同位置,通过指针链接。这种存储方式意味着即使你在遍历 list,相邻元素之间在物理上可能相隔很远,不能保证它们会一起被加载进 CPU 缓存。每次访问一个新的元素可能都需要从主内存中读取,因为这些元素不太可能已经在缓存中。所以 list 在许多情况下比 vector 在性能上要。

应用场景

Vector: 适用于需要频繁随机访问元素的场景,以及在尾部进行插入和删除操作的情况。

List: 更适合频繁在任意位置插入或删除元素的场景,尤其是当元素大小较大或复制成本较高时。

vector 由于其简单性和高性能通常是首选,除非有特定的理由需要使用 list 的特殊能力。

参考:

https://www.cnblogs.com/Sherloy/p/4979159.html

https://www.cnblogs.com/enterBeijingThreetimes/archive/2009/03/15/1412421.html


 

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

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

相关文章

计算机设计大赛 深度学习OCR中文识别 - opencv python

文章目录 0 前言1 课题背景2 实现效果3 文本区域检测网络-CTPN4 文本识别网络-CRNN5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习OCR中文识别系统 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;…

Lag-Llama:第一个时间序列预测的开源基础模型介绍和性能测试

2023年10月&#xff0c;我们发表了一篇关于TimeGPT的文章&#xff0c;TimeGPT是时间序列预测的第一个基础模型之一&#xff0c;具有零样本推理、异常检测和共形预测能力。 虽然TimeGPT是一个专有模型&#xff0c;只能通过API访问。但是它还是引发了对时间序列基础模型的更多研…

Unity如何修改预制体(预制件)?

文章目录 19 复制复制复制&#xff0c;预制体与变体 19 复制复制复制&#xff0c;预制体与变体 【预制件】 预制件作用&#xff1a;方便复用 【预制件】的制作 直接拖拽&#xff0c;从层级面板 -> 项目面板。层级面板中当前图标会变蓝&#xff0c;子物体名字变蓝色。预制件…

[经验] 做完腺样体手术打呼噜很严重怎么办 #媒体#笔记#经验分享

做完腺样体手术打呼噜很严重怎么办 1、打呼噜很严重怎么办 打呼噜是一种常见的睡眠障碍&#xff0c;不仅让睡眠质量变得很糟糕&#xff0c;也会影响室友或家人的睡眠质量。幸运的是&#xff0c;有许多方法可以减少打呼噜的发生率&#xff0c;从而让睡眠变得更好。 保持良好的…

已解决ModuleNotFoundError: No module named ‘tensorflow‘异常的正确解决方法,亲测有效!!!

已解决ModuleNotFoundError: No module named tensorflow异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 文章目录 问题分析 报错原因 解决思路 解决方法 总结 在深度学习和机器学习项目中&#xff0c;TensorFlow是一个极为常用和功能强大…

从零开启 JDBC 编程

前言 最近在总结MyBatis的时候了解到&#xff0c;MyBatis的底层使用的就是JDBC&#xff0c;仔细想想JDBC是我很久之前学过的东西了&#xff0c;现在难免有些遗忘&#xff0c;所以打算重新拿出来写一下&#xff0c;毕竟理解了JDBC的工作原理和原始API的使用&#xff0c;对理解框…

具有集中目录服务器的 P2P 工作方式

P2P 工作方式概述 在 P2P 工作方式下&#xff0c;所有的音频/视频文件都是在普通的互联网用户之间传输。 具有集中目录服务器的 P2P 工作方式 Napster 最早使用 P2P 技术&#xff0c;提供免费下载 MP3 音乐。 Napster 将所有音乐文件的索引信息都集中存放在 Napster 目录服务…

ng : 无法加载文件 C:\Program Files\nodejs\node_global\ng.ps1, 因为在此系统上禁止运行脚本

ng : 无法加载文件 C:\Program Files\nodejs\node_global\ng.ps1&#xff0c;因为在此系统上禁止运行脚本 今天在VSCode中运行ng serve --port 8081运行基于Angular的项目时&#xff0c;报错了&#xff0c;错误如下图所示&#xff1a; 解决方法&#xff1a; 按照下图的5步即…

算法沉淀——哈希算法(leetcode真题剖析)

算法沉淀——哈希算法 01.两数之和02.判定是否互为字符重排03.存在重复元素04.存在重复元素 II05.字母异位词分组 哈希算法&#xff08;Hash Algorithm&#xff09;是一种将任意长度的输入&#xff08;也称为消息&#xff09;映射为固定长度的输出的算法。这个输出通常称为哈希…

七、Mybatis缓存

缓存就是内存中的数据&#xff0c;常常来自对数据库查询结果的保存&#xff0c;使用缓存、可以避免频繁的与数据库进行交互&#xff0c;进而提高响应速度一级缓存是sqlSession级别的缓存&#xff0c;在操作数据库时需要构造sqlsession对象&#xff0c;在对象中有一个数据结构&a…

【智能家居入门3】(MQTT服务器、MQTT协议、微信小程序、STM32)

前面已经写了三篇博客关于智能家居的&#xff0c;服务器全都是使用ONENET中国移动&#xff0c;他最大的优点就是作为数据收发的中转站是免费的。本篇使用专门适配MQTT协议的MQTT服务器&#xff0c;有公用的&#xff0c;也可以自己搭建&#xff08;应该要钱&#xff09;&#xf…

数矩形个数

给定平面整数网格上的点&#xff0c;计算长方形的个数&#xff0c;例如 输入&#xff1a;[(0, 0), (0, 1), (1, 0), (1, 1)] &#xff0c;输出&#xff1a;1​ 输入&#xff1a;[(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]&#xff0c;输出&#xff1a;3 ​ 思路一 每…

【Java程序员面试专栏 分布式中间件】ElasticSearch 核心面试指引

关于ElasticSearch 部分的核心知识进行一网打尽,包括ElasticSearch 的基本概念,基本架构,工作流程,存储机制等,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 基础概念 从数据分类入手,考察全文索引的基本概念 现实世界中数据有哪…

量子算法入门——2.线性代数与复数

参考资料&#xff1a; 【【零基础入门量子计算-第03讲】线性代数初步与复数】 来自b站up&#xff1a;溴锑锑跃迁 建议关注他的更多高质量文章&#xff1a;CSDN&#xff1a;【溴锑锑跃迁】 0. 前言 强烈建议搭配b站原视频进行观看&#xff0c;这只是我当时看的笔记&#xff0c…

Vue路由的传参

Vue传参方式可以划分为params传参&#xff08;参数隐藏在路径中&#xff09;和query传参&#xff08;参数在&#xff1f;后&#xff09;俩种方式 1. 使用 router-link 标签跳转路由 要注意 to 和 :to 的不同&#xff1a; to 不带参数 &#xff0c; :to 带参数 &#xff0…

【机器学习笔记】4 朴素贝叶斯

贝叶斯方法 贝叶斯分类 贝叶斯分类是一类分类算法的总称&#xff0c;这类算法均以贝叶斯定理为基础&#xff0c;故统称为贝叶斯分类。 朴素贝叶斯分类是这一类算法中最简单的较为常见的算法。 先验概率 根据以往经验和分析得到的概率。我们用&#x1d443;(&#x1d44c;)来代…

FL Studio 21.2.3.4004 All Plugins Edition Win/Mac音乐软件

FL Studio 21.2.3.4004 All Plugins Edition 是一款功能强大的音乐制作软件&#xff0c;提供了丰富的音频处理工具和插件&#xff0c;适用于专业音乐制作人和爱好者。该软件具有直观的用户界面&#xff0c;支持多轨道录音、混音和编辑&#xff0c;以及各种音频效果和虚拟乐器。…

【pandas 不同文件读取和存储】

文章目录 一、Pandas 文件读取和存储概览二、读取不同类型的文件1. CSV文件的读取与存储代码及解释&#xff1a; 2. Excel文件的读取与存储代码及解释&#xff1a; 3. JSON文件的读取与存储代码及解释&#xff1a; 4. SQL数据库的读取与存储代码及解释&#xff1a; 5. 其他格式…

华清远见嵌入式学习——春节作业——2.15日

作业要求&#xff1a; 编写led驱动&#xff0c;通过应用程序控制三盏灯亮灭 作业答案&#xff1a; 作业效果&#xff1a; mychrdev.c #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/uaccess.h> #incl…

springboot声明(创建)RabbitMQ交换机和队列

在之前我们都是基于RabbitMQ控制台来创建队列、交换机。但是在实际开发时&#xff0c;队列和交换机是程序员定义的&#xff0c;将来项目上线&#xff0c;又要交给运维去创建。那么程序员就需要把程序中运行的所有队列和交换机都写下来&#xff0c;交给运维。在这个过程中是很容…