C++ STL容器比较--读《C++标准程序库》总结

Vectors
Vectors 是一种有序群集,vector支持随机存取,因此只要知道位置,你可以在常数时间内存取任何一个元素。Vector的迭代器是随机存取迭代器,所以任何一个STL算法都可以凑效。
在末端附加或删除元素时,vector的性能相当好,可是如果在前端或中部安插或删除元素,性能就不怎么样了,因为操作点之后的每一个元素都必须移到另一个位置,而每一次移动都得调用assignment(赋值)操作。
关于性能,一下情况你可以预期安插操作和移除操作会比较快些;
1、在容器尾部安插或移除元素
2、容量一开始就够大
3、安插多个元素时,调用一次比调用多次来的快,安插元素移除元素,都会使作用点之后的各元素的reference、pointers、iterators失效。如果安插操作甚至引发内存重新分配,那么该容器身上的所有reference、pointers、iterators都会失效。

C++标准程序库并未明确要求vector的元素必须分布于连续的空间中。但是一份标准规格缺陷报告显示,这个缺点将获得弥补。标准规格书中将明确保证上述论点。如此一来你可以确定对于vector V中任何一个合法索引1,以下表达式肯定为TRUE,
&V[i]==&V[0]+i
保证了这一点,任何地点只要你需要一个动态数组,你就可以使用vector,如
Std::vector<char> V;
V.resize(41);
Strcpy(&V[0],”HELLO,WORLD”);
Printf(“%s\n”,&V[0]);
不过,这么使用vector你必须小心,例如确保上述vector的大小足以容纳所有数据,如果你用的是C-String,记住最后有个’\0’。

Deques

采用动态数组来管理元素,提供随机存取,并有着和vector几乎一模一样的接口,不同的是deques的动态数组头尾都开放,因此能在头尾两端进行安插和删除。如下图所示:

                                              

为了获得这种能力,deques通常实作为一组独立区块,第一区块朝着某方向扩展,最后一个区块朝着另一个方向扩展,如下图;

                                                             

Deques的能力,与vector不同deques在于以下几点;
1、两端都能快速安插元素和删除元素,这些操作可以在分期摊还的常数时间内完成。
2、存取元素时,deques的内部结构会多一个间接过程,所以元素的存取和迭代的动作会稍微慢一些。
3、迭代器需要在不同区块见跳转,所以必须是特殊的智能指针,非一般指针。
4、在对内存区块有所限制的系统中,deque可以包含更多元素,因为它使用不止一块内存。因此deque的max_size()可能更大。
5、deque不支持对容量和内存重分配时机的控制。特别注意的是,除了头尾两端,在任何地方安插或删除元素,都会导致指向deque元素的任何pointers、references、iterators失效。不过,deque的内存分配由于vector,因为其内部结构显示,deques不必再内存重新分配时复制所有元素。
6、deque的内存块不在被使用时,会被释放。deque的内存是可以缩减的,根据具体实作版本确定。

与vector功能差不多如下几点:
1、在中段部分安插或删除元素时速度较慢,因为所有元素都需要移动以腾出或填补空间。
2、迭代器属于随机存取迭代器。
总之以下情形最好采用deque:
1、你需要在两端安插和移除元素(这是deque的拿手好戏)。
2、无需医用容器内的元素。
3、要求容器释放不再使用的元素
Vector与deques的接口几乎一样,所以如果无需什么特殊性质,两者都可试试。

List
List 使用一个双向链表来管理元素,如下图所示:

              

List的能力:

1、List的内部结构和vector或deque 截然不同,所以在几个主要方面与前述二者存在明显差别;
2、List不支持随机存取,如果你需要区地5个元素,就得顺着窜链一一爬过前面4个元素。所以,在list中随机遍历任意元素,是很缓慢的行为。
3、任何位置上(不只是两端)执行元素的安插和移除都非常快。因为无需移动仍和其他元素,实际上内部知识进行了一些指针操作而已。
4、安插和删除动作并不会造成指向其他各元素的各个pointers、reference、iterators失效。
5、List对异常的有着这样的处理方式:要么操作成功,要么什么都不发生。


List与vector和deques的不同:
1、由于不支持随机存取,list既不提供下标操作,也不提供at().
2、List并未提供容量、空间重置分配等操作,因为全无必要。每个元素都有自己的内存,在被删除之前一直有效。
3、List提供了不少特殊的成员函数,专门用于移动元素,较之同名的STL通用算法,这些函数执行起来更快,因为它们无需拷贝或移动,只需调整若干指针即可。

 

猜你喜欢

转载自blog.csdn.net/cindywry/article/details/85254549