1. vector
就是一个在堆上建立的一维数组,因为在堆上,所以对其进行erase( ), resieze()等操作;还有一点就是,vector不用担心越界当空间不够用的时候,系统会自动按照一定的比例(对capacity( )大小)进行扩充。 vector最大的优点莫过于是检索(用operator[ ])速度在这三个容器中是最快的,还有就是在vector序列末尾添加(push_back( ))或者删除(pop_back( ))对象效率高,其它的操作的效率都谈不上很NB,原因就在于当内存不够用的时候要执行重新分配内存,拷贝对象到新存储区,销毁old对象,释放内存等操 作,如果对象很多的话,这种操作代价是相当高的。为了减少这种代价,使用vector最理想的情况就是事先知道所要装入的对象数目,用成员函式 reserve( )预定下来;
优点: (1) 不指定一块内存大小的数组的连续存储,即可以像数组一样操作,但可以对此数组
进行动态操作。通常体现在push_back() pop_back()
(2) 随机访问方便,即支持[ ]操作符和vector.at()
(3) 节省空间。
缺点: (1) 在内部进行插入删除操作效率低。
(2) 只能在vector的最后进行push和pop,不能在vector的头进行push和pop。
(3) 当动态添加的数据超过vector默认分配的大小时要进行整体的重新分配、拷贝与释放
2.deque(double-ended-queue)
由多个连续内存块构成,同时存在一个映射表对这些内存块进行管理【貌似在OS课程上讲过】。同理该容器也有索引操作operator[ ],效率没vector高。但是,双端队列几乎不存在上述的操作,自然在同等条件下效率好多了。另外,deque比vector多了push_front( ) & pop_front( )操作,灵活性更大。
注:
- deque是由一系列分段的数组组成,它们的首地址被记录在一个索引数组中,可以随机访问,但是效率要低于向量。
- 它可以在两端高效的添加元素,因为当两端的数组满了以后秩序新建一个数组即可。
- 在两端新加数组的时候所有的迭代器会失效,但是数组和引用没有,因为它们的地址没有改变。
- 当删除中间元素的时候会将其插入点到一端的元素全部移动,具体向哪一端移动取决于STL实现,所有的迭代器和指针会失效。
优点: (1) 随机访问方便,即支持[ ]操作符和vector.at()
(2) 在内部方便的进行插入和删除操作
(3) 可在两端进行push、pop
缺点: (1) 占用内存多
3. list
的本质是一个双向链表,说道链表,它的高效率首先表现是插入,删除元素,进行排序等等需要移动大量元素的操作。显然链表没有检索操作operator[ ], 也就是说不能对链表进行随机访问,而只能从头至尾地遍历,这是它的一个缺陷。list有不同于前两者的某些成员方法,如合并list的方法splice( ), 排序sort( ),交换list 的方法swap( )等等。
优点:(1) 不使用连续内存完成动态操作。
(2) 在内部方便的进行插入和删除操作
(3) 可在两端进行push、pop
缺点:(1) 不能进行内部的随机访问,即不支持[ ]操作符和vector.at()
(2) 相对于verctor占用内存多
下面是选择顺序容器类型的一些准则
如果我们需要随机访问一个容器则vector要比list好得多 。
如果我们已知要存储元素的个数则vector 又是一个比list好的选择。
如果我们需要的不只是在容器两端插入和删除元素则list显然要比vector好
除非我们需要在容器首部插入和删除元素否则vector要比deque好