序列容器:vector,deque,list

来源:互联网 发布:尼泊尔弯刀淘宝 编辑:程序博客网 时间:2024/05/16 15:58

一,容器的通性

1,将元素插入容器进行了一次拷贝操作,如果想要实现类似于”引用”的情况,可以用指针.

2,容器中的元素是有序的,即用一个iter从begin遍历到end,多次运行得到的结果是相同的.

3,一般有如下API:

a)     构造函数通常有这三种:ContType c, ContType c1(c2),ContType c(beg,end)

b)     支持各种赋值(=)和比较运算符(==,>,<等),按字典顺序进行比较

c)      支持迭代器:begin(),end(),rbegin(),rend()

d)     支持移动构造函数c1.swap(c2)和swap(c1,c2)

e)     插入函数叫insert,删除叫erase,erase会调用被删除元素的析构函数

f)       有如下几个大小相关的函数:size(),empty(),max_size()

二,Vector

1,可以将vector看成一个数组(动态的),这意味着它的查找,插入/删除操作的复杂度都是O(n),但从尾部插入/删除的复杂度是O(1),而且有一个很重要的能力:随机存取

2,既然是连续存储, 就必然涉及到内存问题. Vector有几个操作内存的函数,如max_size,reserve,capacity等,但通常你用不到他们,这是因为:

a)     Vector预先分配了很大的空间,通常情况下你用不完它们(事实是大数据量的情况通常不采用vector来存,O(n)的找速度很蛋疼)

b)     预先reserve出更大的空间可以节省重新配置内存的时间,但节省时间的效果并不是很明显,因为重新配置内存可能比预想的快得多. 更明显的好处是可以节省空间,因为重新分配内存时需要而被的空间消耗.

c)      Reserve只能增大内存,不能减少,而且reserve是有可能失败的(内存不足). 减少可以用swap:

vector tmp;

v.swap(tmp)

tmp.clear()

      这条规则的另一个效果是你无法弄出一个maxsize小于系统默认值的vector来=_=

3,vector的随机存储可以用下标,也可以用at()函数,区别是at()有可能报异常

4,一次插入多个元素比一个一个插入多次要省一些时间.当然还是尽量用push_back

5,vector的元素分布于连续空间中,因此可以把vector当一个数组来操作

6,vector<bool>是一个特殊的版本,可以大量节省内存,相当于一个可动态扩展的bitsets但不是很常用(至少在互联网)

7,vector的另一个重要特性是不能直接释放内存, 即使你把一个

三,Deque

Deque(音deck)与vector非常像,基本可以理解为一个可以从头部插入元素的vector. 这个能力看起来很美,但实际中需要的场合不多,事实上vector远比deque常用.

与vector比的优点:

1.      可以从头部存储,复杂度O(1)

2.      使用不止一块内存,因此可以有比vector更大的maxsize,而且可以直接释放内存(vector也可以通过swap释放)

缺点:

1.      存取元素时的效率要低一些

2.      插入一个元素会使所有的元素的引用失效(vector仅后面的元素失效)

3.      插入/删除中间元素比vector更慢(虽然都是O(n))

API区别:

1.      多一个push_front和pop_front

2.      没有capacity和reserve

 

四,List

list是用一个双向链表实现的,因此其特性与vector区别很大:

1,拥有O(1)的插入/删除能力

2,不具有随机访问能力

3,无需任何内存分配等操作

4,插入和删除操作不会使任何元素的指针,引用和迭代器失效

 

API函数:

1,remove和remove_if函数提供了移除确定值的功能,比通用算法更快

2,sort,排序不能使用通用算法里的sort,需要用其自己的成员函数sort

3,merge, 对有序列表进行merge,与sort一起,不错的功能

4,splice系列,将一条链表(的一部分)加到另一条链表中

5,reverse, 反序,速度很快

6,对比vector的push_back和list的push_back的速度

7,对比vector和list的空间消耗

 

五,list与vector性能的比较

速度上vector和list各有千秋,当插入或移动元素时, vector需要拷贝&移动元素数据, 而list无需移动元素本身,但需要处理一些额外的指针,而且可能需要为每个元素申请&分配内存.  因此当处理简单类型(如int)时,vector速度更快, 当处理复杂类型时(如class,struct) list更快,  但总得来说二者的速度都在一个数量级上.


原创粉丝点击