首页 > 其他分享 >vector,list,deque,set,map of STL

vector,list,deque,set,map of STL

时间:2023-04-28 17:42:01浏览次数:29  
标签:deque set map list 链表 vector 内存 数组


List封装了链表,Vector封装了数组, list和vector得最主要的区别在于vector使用连续内存存储的,他支持[]运算符,而list是以链表形式实现的,不支持[]。

Vector对于随机访问的速度很快,但是对于插入尤其是在头部插入元素速度很慢,在尾部插入速度很快。List对于随机访问速度慢得多,因为可能要遍历整个链表才能做到,但是对于插入就快的多了,不需要拷贝和移动数据,只需要改变指针的指向就可以了。另外对于新添加的元素,Vector有一套算法,而List可以任意加入。
Map,Set属于标准关联容器,使用了非常高效的平衡检索二叉树:红黑树,他的插入删除效率比其他序列容器高是因为不需要做内存拷贝和内存移动,而直接替换指向节点的指针即可。
Set和Vector的区别在于Set不包含重复的数据。Set和Map的区别在于Set只含有Key,而Map有一个Key和Key所对应的Value两个元素。
Map和Hash_Map的区别是Hash_Map使用了Hash算法来加快查找过程,但是需要更多的内存来存放这些Hash桶元素,因此可以算得上是采用空间来换取时间策略。

vector - 会自动增长的数组


vector又称为向量数组,他是为了解决程序中定义的数组是
不能动态改变大小这个缺点而出现的。
一般程序实现是在类创建的时候同时创建一个定长数组,
随着数据不断被写入,一旦数组被填满,则重新开辟一块更大的内存区,
把原有的数据复制到新的内存区,抛弃原有的内存,如此反复。

由于程序自动管理数组的增长,对于我们程序员来说确实轻松了不少,
只管把数据往里面插就行了,当然把物理内存和虚拟内存插爆掉了
就是操作系统来找你麻烦了:-)

vector由于数组的增长只能向前,所以也只提供了后端插入和后端删除,
也就是push_back和pop_back。当然在前端和中间要操作数据也是可以的,
用insert和erase,但是前端和中间对数据进行操作必然会引起数据块的移动,
这对性能影响是非常大的。

对于所有数组来说,最大的优势就是随机访问的能力。
在vector中,提供了at和[]运算符这两个方法来进行随机访问。
由于每个数据大小相同,并且无间隔地排列在内存中,
所以要对某一个数据操作,只需要用一个表达式就能直接计算出地址:
address = base + index * datasize

同样,对vector进行内存开辟,初始化,清除都是不需要花大力气的,
从头到尾都只有一块内存。


list - 擅长插入删除的链表


有黑必有白,世界万物都是成对出现的。
链表对于数组来说就是相反的存在。
数组本身是没有动态增长能力的(程序中也必须重新开辟内存来实现),
而链表强悍的就是动态增长和删除的能力。
但对于数组强悍的随机访问能力来说的话,链表却很弱。

list是一个双向链表的实现。
为了提供双向遍历的能力,list要比一般的数据单元多出两个指向前后的指针。
这也是没办法的,毕竟现在的PC内存结构就是一个大数组,
链表要在不同的环境中实现自己的功能就需要花更多空间。

list提供了push_back,push_front,pop_back,pop_front四个方法
来方便操作list的两端数据的增加和删除,不过少了vector的at和[]运算符的
随机访问数据的方法。并不是不能实现,而是list的设计者
并不想让list去做那些事情,因为他们会做得非常差劲。

对于list来说,清除容器内所有的元素是一件苦力活,
因为所有数据单元的内存都不连续,list只有一个一个遍历来删除。


deque - 拥有vector和list两者优点的双端队列


黑与白,处于这两个极端之间的就是令人愉悦的彩色了。
deque作为vector和list的结合体,确实有着不凡的实力。

STL的deque的实现没有怎么去看过,不过根据我自己的猜测,
应该是把数组分段化,在分段的数组上添加指针来把所有段连在一起,
最终成为一个大的数组。

deque和list一样,提供了push_back,push_front,
pop_back,pop_front四个方法。可以想象,如果要对deque的两端进行操作,
也就是要对第一段和最后一段的定长数组进行重新分配内存区,
由于分过段的数组很小,重新分配的开销也就不会很大。

deque也和vector一样,提供了at和[]运算符的方法。
要计算出某个数据的地址的话,虽然要比vector麻烦一点,
但效率要比list高多了。
首先和list一样进行遍历,每次遍历的时候累积每段数组的大小,
当遍历到某个段,而且baseN <= index < baseN + baseN_length的时候,
通过address = baseN + baseN_index就能计算出地址
由于分过段的后链表的长度也不是很长,所以遍历对于
整体性能的影响就微乎其微了。

看起来deque很无敌吧,不过deque和希腊神话的阿吉里斯一样,
再怎么强大也是有自己的弱点的,之后的测试数据中就能看到了。

标签:deque,set,map,list,链表,vector,内存,数组
From: https://blog.51cto.com/u_130277/6235013

相关文章

  • vue3 获取asset文件夹下所有资源文件列表
     参考链接:https://www.jianshu.com/p/0f4386d19c07importpathfrom"path"; constgetLayerBgs=function(){ constimgs:any=[]; //获取所有背景图层 //读取文件的路径是否遍历文件的子目录匹配文件正则表达式 constfiles=require.context("@/a......
  • 【解决】axios 下载文件 Failed to read the 'responseText' property from 'XMLHttp
    主要解决以下两个问题问题一:idm一些网站不允许请求同一文件两次故障原因:IDM在发神经因为它检测到浏览器集成插件未安装,所以诱导你安装。实际上,装了插件问题也会出现。改参数都没用。1.很可能是你点击网页的下载链接有问题(换个网页下载试试,就不提示了),Edge浏览器一直会欺......
  • Python rangelib.RangeSet类代码示例
    https://vimsky.com/examples/detail/python-ex-rangelib-RangeSet---class.htmlPythonrangelib.RangeSet类代码示例本文整理汇总了Python中rangelib.RangeSet类的典型用法代码示例。如果您正苦于以下问题:PythonRangeSet类的具体用法?PythonRangeSet怎么用?PythonRangeSet使......
  • 解决 VMware 虚拟机 Linux /dev/mapper/ubuntu--vg-ubuntu--lv 磁盘空间不足的问题
    之前在VMware安装UbuntuServer的时候磁盘分区选择了LVM,所以系统根目录默认占用磁盘大小只有4G,在安装软件时发现磁盘空间4G已经无法满足,所以需要利用LVM对磁盘进行扩容使用Docker拉取MySQL镜像时发现磁盘空间不够:nospaceleftondeviceroot@ubuntu:~#......
  • GMaps.js:让你快速集成 Google Maps 服务的 jQuery 插件
    GMaps.js功能除了添加指定经纬度的标准地图之外,GMaps.js还能定义地图放大的级别,添加标注,获取当前用户的地理位置(HTML5geolocation),定义路线,绘制折线,并且实现这些功能只需要简单的几行代码。另外GMaps.js每个动作都有callback函数让你去集成自定义事件。目前GMaps.js没有详......
  • BigDecimal的setScale常用方法(ROUND_UP、ROUND_DOWN、ROUND_HALF_UP、ROUND_HALF_DOW
    BigDecimal的setScale四大常用方法总结//设置小数点后第三位数字一大一小观察效果BigDecimalnum=newBigDecimal("3.3235667");BigDecimalnumOne=newBigDecimal("3.3275667");1、ROUND_UP:进位制:不管保留数字后面是大是小(0除外)都会进1//ROUND_UP--进位制:不管保留数......
  • YOLOV5训练时MAP、R、P值为0,测试时无检验框
    YOLOV5训练时MAP、R、P值为0,测试时无检验框问题引出:​今天帮一个大三的学生,跑yolov5,首先我观察他电脑的配置:显卡是GTX1650,进入英伟达控制面板发现他最高支持的cuda版本的是11.7,便给他装了11.6的cuda和cudnn,但是训练的过程中,发现出现了一段警告,警告的内容为:C:\User......
  • Semaphore源码分析
    1、Semaphore介绍计数信号量-Semaphore,常用来限制访问资源的线程数量。优点类似限流中的令牌桶算法,只有拿到信号量的线程才能执行,与令牌桶算法未拿到令牌不处理请求不同的是,在Semaphore中未拿到信号量的线程会阻塞等待,直到有某个线程释放了持有的信号量。2、Semaphore使用......
  • Python-集合的基本操作(set)
    1. 前言python中的集合和数学里的类似也是用于存放不重复的元素,它有可变集合(set)和不可变集合(feozenset)两种,集合的所有元素都放在一对大括号"{}"里(列表是[]、元组是()、字典是{}),集合最好的应用就是去重,因为集合中的每一个元素都是唯一的。 2. 集合的创建2.1.直接使用"{}"创......
  • Java把实体转为map对象
    方式一importorg.springframework.cglib.beans.BeanMap;BeanMap.create(entityObj); 方式二importcom.alibaba.fastjson.JSONObject;//方式1、强转为JSONObjectJSONObjectxxx=(JSONObject)JSONObject.toJSON(xxxEntity);//方式2、转成json,在转为mapStringjs......