c++各容器使用心得

STL中的常用容器包括:顺序性容器(vector、deque、list)、关联容器(map、set)、容器适配器(queue、stack)。

其中vector表示一段连续的内存,基于数组实现,list表示非连续的内存,基于链表实现,deque与vector类似,但是对首元素提供插入和删除的双向支持。

map是key-value形式,set是单值。map和set只能存放唯一的key,multimap和multiset可以存放多个相同的key。

容器类自动申请和释放内存,因此无需new和delete操作。


1、vector

vector采用一段连续内存存其元素,元素下标快速访问随机的元素,find()成员函数对元素采用从头到尾扫描的方式查找,快速在末尾插入元素,但是在序列中间随机的插入、删除元素要慢。

头部插入:将所有元素后移,然后将新元素插入

中间插入:将插入点后面的元素后移,然后插入新元素

尾部插入:将新元素直接插入尾部

尾部插入无疑是最快的,头部插入最慢,中间插入次之,慢的点在于插入前要移动内存。

技巧:向vector添加元素的时候,如果容量不足,vector便会重新malloc一段更大的内存,然后把原内存中的数据memcpy到新的内存中,并free原内存块,然后将新元素加入。

使用时机:缺省情况下应该使用vector。vector的内部结构最简单,并允许随机存取,所以数据的存取十分方便灵活,数据的处理也够快。


2、deque

小块连续,小块间用链表相连,多块内存串起来的方式提供其元素存储,每个内存块存储多个元素,每一块内存存储的元素个数相同,实际上内部有一个map的指针,只是速度没有vector快。

快速的访问随机的元素,快速的在开始和末尾插入元素。随机的插入删除元素要慢,空间的从新分配空间后,原有的元素不需要备份。

好处是:

首先,头部插入和尾部插入/删除元素的成本是一样,弥补了vector再头部插入元素性能不佳的问题;

其次,对于vector的一个内存块的模式,当有巨大数量的元素,操作系统的大内存分配和赋值时很缓慢的,而且deque的方式就不会带来这个问题。

缺点是:

首先对元素的访问需要经过两个层次,第一次找到元素所在的内存块,第二次找到块中的元素。不过这个时间几乎是可以忽略,除非对性能要求极其苛刻。

其次,对其进行排序,以及排序后的查找会比较慢。对deque的排序操作,可将deque先复制到vector,排序后再复制回deque。

技巧:对deque的排序操作,可将deque先复制到vector,排序后再复制回deque。

使用时机:如果经常要在序列头部和尾部安插和移除元素,应该采用deque。如果希望元素被移除时,容器能够自动缩减内存,那么也应该采用deque。


3、list

list是个双向链表。每一个元素的内存都是独立的,用链表相连,访问随机元素没有vector快,随机地插入元素要比vector快,对每个元素分配空间,不存在空间不够,重新分配的情况。

优点是:

任何位置的插入删除元素操作都是非常块的。

缺点是:

不适合用于元素的查找,只能扫描的方式。从实际使用情况来看,节点的频繁新增与删除将导致大量重复的内存分配和释放操作。

使用时机:如果需要经常在容器的中执行元素的安插、移除和移动,可考虑使用list。list提供特殊的成员函数,可以在常数时间内将元素从A容器转移到B容器。但由于list不支持随机存取,所以如果只知道list的头部却要造访list中的元素,性能会大打折扣。


4、set

set容器只是单纯的元素的集合,内部元素唯一,用一棵平衡树结构来存储,因此遍历的时候就排序了,查找也比较快。不支持下标操作。

作为标准库的一个关联容器,内部元素进行了排序,使用这特性可以对一组元素进行插入排序。set最初的设计是完成数学中“集合”的概念。

使用时机: 如果你经常需要根据某个准则来搜寻元素,那么应当使用“以该排序准则对元素进行排序”的set或multiset。


5、map

map一对一地映射结合,key没有重复,在一些程序中建立一个map可以起到事半功倍的效果。

map是一类关联式容器。它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。

对于迭代器来说,可以修改实值,而不能修改key。

使用时机:如果想处理key/value pair,关联式数组或字典结构,应采用map/multimap


6、queue

queue是一个队列,实现先进先出功能,queue不是标准的STL容器,却以标准的STL容器为基础。queue是在deque的基础上封装的。之所以选择deque而不选择vector是因为deque在删除元素的时候释放空间,同时在重新申请空间的时候无需拷贝所有元素。

queue的声明queue<int,deque > s,是受限的队列,存储的空间由第二个参数的容器确定,第一个参数在没有第二个参数的情况下,决定存储空间类型,第二个参数存在的情况下,第一个类型参数无效。默认情况下队列存储空间就是deque。另外,queue第二个参数可以选择的容器类型包括deque、list,操作受限。


7、stack

stack的默认存储空间也是deque,其他的声明和queue差不多,可以使用的容器类型包括deque、vector、list,stack是先进后出栈。

stack是实现先进后出的功能,和queue一样,也是内部封装了deque,这也是称为容器适配器的原因。自己不直接维护被控序列的模板类,而是它存储的容器对象来实现所有的功能。stack的源代码原理和实现方式均跟queue相同。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值