首页 > 其他分享 >从时间复杂度的角度出发,list和vector之间查找,插入,删除等数据操作的区别

从时间复杂度的角度出发,list和vector之间查找,插入,删除等数据操作的区别

时间:2024-03-20 19:22:22浏览次数:25  
标签:删除 复杂度 元素 list 插入 vector

list和vector是STL(标准模板库)中常用的两种序列容器,它们各自在不同类型的操作上有着不同的优势。下面是list和vector在不同操作上的擅长之处:

list的擅长操作
插入和删除操作:list是一个双向链表,插入和删除元素时只需要调整相邻节点的指针,因此在中间或任意位置插入或删除元素时效率很高,时间复杂度为O(1)。

迭代器失效风险低:由于数据存储在节点中,当插入或删除元素时,并不会使得迭代器失效,使得list在需要频繁插入、删除或移动元素并需要使用迭代器访问数据时是一个不错的选择。

不需要连续内存:list的元素在内存中不需要连续存储,这使得list更适合于大量的动态插入和删除操作。

vector的擅长操作
随机访问:vector是一个动态数组,支持高效的随机访问,通过索引(下标)可以在O(1)的时间复杂度内访问元素,使其非常适合需要快速访问元素而不需要频繁插入和删除操作的场景。

快速末尾操作:在末尾进行插入和删除操作时,vector的效率很高,插入和删除末尾元素的时间复杂度为摊销的O(1)。

连续内存存储:vector中的元素是连续存储的,这样有利于提高缓存命中率,从而提高访问速度,特别是在大规模数据集上可能会有更好的性能表现。

结论
在选择使用list还是vector时,需要根据具体应用场景的需求进行合理的选择。如果需要频繁的插入和删除操作,尤其是在中间位置,那么list可能更适合。如果需要高效的随机访问和在末尾进行插入/删除操作,那么vector可能更适合。同时,在实际使用中,也可以根据具体问题的特点结合使用这两种容器,以发挥它们各自的优势来提高程序性能。
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
从时间复杂度的角度分析,list和vector各自的数据操作性能有显著不同,主要由于它们的内部数据结构导致。list是一个双向链表,而vector是一个动态数组。下面是对这两种容器中查找、插入和删除操作的比较:

查找
Vector (std::vector): 查找(无论是顺序查找还是使用算法如二分查找)的时间复杂度通常是O(n),因为最坏情况下可能需要遍历整个数组。如果数组已排序,可以使用二分查找,时间复杂度为O(log n)。

List (std::list): 查找的时间复杂度是O(n),因为list是一个链表,无法直接访问中间的元素,必须从头(或尾)开始遍历。

插入
Vector (std::vector):

在vector的末尾插入元素的复杂度是摊销的O(1)。摊销是因为vector可能需要扩容,这需要复制现有元素到一个新的更大的数组中,但这种情况不频繁发生。
在vector的中间或开始位置插入元素的复杂度是O(n),因为插入位置之后的所有元素都需要向后移动以腾出空间。
List (std::list): 插入的时间复杂度是O(1),如果你已经有了指向插入位置的迭代器。这是因为链表插入不需要移动其他元素,只要修改前后节点的指针即可。

删除
Vector (std::vector):

从末尾删除元素的时间复杂度是O(1)。
从vector的中间或开始位置删除元素的复杂度是O(n),因为删除元素后,后面的所有元素都需要向前移动来填补空位。
List (std::list): 删除的时间复杂度是O(1),如果你已经有了指向被删除元素的迭代器。类似于插入操作,删除不需要移动其他元素,仅需修改相邻节点的指针。

总结
总的来说,list在插入和删除操作上特别高效,特别是在列表的中间或特定位置操作时。而vector在末尾插入或删除操作上很高效,且支持快速随机访问,使得查找操作(特别是经过优化的查找算法)在已排序的数组中效率更高。因此,在选择使用list还是vector时,需要考虑应用的需求,特别是操作的类型(插入/删除的位置,访问的频繁程度)以及对时间效率的要求。

标签:删除,复杂度,元素,list,插入,vector
From: https://www.cnblogs.com/VisionSeven/p/18085903

相关文章

  • Yolov9报错“IndexError: list index out of range”方法解决
     哈喽友友们好!今天继续分享关于yolov9的使用教程。 在使用yolov9的数据集时,你是否有类似的报错?如图作者本人一直查找问题,开始是想着数据集标签可能有问题,于是就更换数据集直到适合为止。但发现很多数据集还是会报这个错,只有少部分才能运行,这个方法治标不治本。 于是......
  • WPF MVVM模式ListBox下ContextMenu绑定Command的方法以及将所选的Item的数据传回去
    需求:ListBoxItem上右键,将数据传参。疑问:ContextMenu不继承DataContext,导致直接用RelativeSource找根的方式也绑定不到。解决方法:在ListBox.ContextMenu里写菜单,就可以直接绑定到ViewModel层的命令了,参数先用RelativeSource找到ContextMenu,再绑定PlacementTarget.SelectedItem。......
  • C# List排序
    先是Y_FaceItem类usingDlibDotNet;usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassY_FaceItem:MonoBehaviour{publicfloatfinalValue;publicTexture2DfaceTextrue;publicintid;publicstring......
  • 复杂度分析
     复杂度分析是算法中非常重要的一点,只有做了复杂度分析才能判断自己目前选择的方案是否是最适合了,所以我们应该花一些时间在理解的基础上去掌握如何分析一段代码复杂度时间复杂度概念:时间复杂度全称为渐进时间复杂度,表示算法的执行时间与数据规模之间的增长关系。几种常见......
  • 深入解析Java中的Vector集合类!
      咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及JavaSE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~......
  • [Java基础学习][集合]java常见集合:Java中集合框架提供了大量的集合类:常见的list、set
    总结与区别:Set:去重;      set去重本质:equals+hashcode;    常见的HashSet、TreeSet。    HashSet基于哈希表实现,插入、删除、查找。不保证顺序    TreeSet基于红黑树实现,保证顺序,查找较快;treeSet:排序继承comparable接口进行比较排序   Se......
  • int[] 、 list<int> 、 list<int>[] 的区别
    同时遇到了这几个,突然有点懵,记一下。int[]是指一个int类型的数组,即一个数组,里面的数据都是int类型; list<int>是指int类型的列表。 list<int>[v]是指一个长度为v的int类型的列表  List<int>和int[]都可以用来存储整数集合,但它们之间有一些重要的区别:大小可变性:List<int......
  • vector的Erase相关
    vector<int>Vect; Vect.insert(Vect.begin()+2,50); for(autoit=Vect.begin();it!=Vect.end();++it) { if(*it==50) { Vect.erase(it); } }为什么以上的代码会报错,而下面的一段代码不会报错? vector<int>Vect;Vect.insert(Vect.begin()+2,50);......
  • STL:vector中如何使用at()来避免程序报错
     #include<iostream>#include<vector>usingnamespacestd;intmain(){ vector<int>Vec; for(inti=0;i<30;i++) { Vec.push_back(i); //cout<<Vec.size()<<endl; //cout<<Vec.capacity()<......
  • CMakeLists.txt基本语法及使用
    1、cmake的说明cmake是一种高级编译配置工具当多个人用不同的语言或者编译器开发一个项目,最终要输出一个可执行文件或者共享库(dll,so等等)这时候便需要用到cmake。CMakeList.txt中指令不区分大小写。CMakeList.txt中的参数和变量是区分大小写,名称只能用字母,数字,下划线,破折号。......