C++中list、deque以及vector对比

来源:互联网 发布:储罐设计软件 编辑:程序博客网 时间:2024/05/16 17:25

C++中list、deque以及vector对比

C++的容器类包括两大类:

1.顺序存储结构,包括vector、list、deque等等;
2.关联存储结构,包括set、map、multiset等等;

本文主要对比vector、list以及deque这三种顺序存储结构。

注:

顺序存储结构表明,其中的每个元素之间是有先后顺序的,这个顺序只和插入/删除等操作有关,而与元素的值无关。


一、vector

vector本身是向量的意思,也称vector是向量数组。

vector本身是为了解决数组不能动态增长,而自己实现的类还需要自己小心翼翼地处理指针和malloc等问题,所以衍生出vector。

vector中的每个元素在内存上是连续的,就像数组一样;

vector支持高效的随机访问(使用[]运算符或者at方法);

所谓随机访问,是可以直接计算出对应元素的地址,假设起始地址是base,每个元素占空间大小是element_size,那么当我存取第n个元素时,我可以直接计算出其对应的地址:

第六个元素的地址=base+element_size*(n-1)

不必要类似链表一样遍历,效率明显很高。

vector支持高效的在末尾插入和删除。

注意:

此处特别强调是在末尾,想一想,一个数组,在哪里插入和删除最为容易?

显然是末尾。

如果在数组中间插入或删除,需要将之后的所有元素都向前/向后移动,无疑增加了开销。

可以将vector看成是一个数组,区别于普通的数组,vector拥有自动扩展内存空间的能力(不必程序员自己管理内存空间)。

vector有一个capacity方法,其返回值是当前vector已经分配了多少个空间用来存储element。

这些空间不一定全被“装满”了,可能只装了一部分。

在装满(vector.size()==vector.capacity())的情况下继续装(vector.push_back(xxx))时,vector自动扩大内存:

首先申请一块更大的内存空间;
其次将vector现有的元素都搬过去;
最后将需要插入的元素插入到末尾。

注意:

在上述的步骤中还要将原来使用的内存空间释放。
程序员无需关心什么时候释放等等细节,vector会自己做的。
程序员只要一个push_back即可。

关于vector的成员函数说两句:

szie以及capacity返回的都是元素的个数,是以元素来计数的,而不是字节。

vector支持在末尾进行pop和push,但不支持在首进行pop和push。

当然,如果一定要在前面插入,vector也是有对应的insert和erase的,只是由于必然引起数据块的移动,所以性能很低。


二、list

list是一个非连续的顺序结构,每个元素在内存上都不是挨着的。

list是一个双向链表,即每个节点都有两个指针域:

一个指向前驱节点,一个指向后继节点。

list同普通的链表一样,对待插入删除这样的操作可以有很高的效率;

同样,对于随机访问的能力就不尽如人意,效率很差了。

list在存储大的,复杂的数据时有很不错的表现。

list有几个优点:

首先list不使用连续的内存;
其次在插入和删除方面有很好的性能;
最后是可以在两端进行pop和push(vector只能在尾端进行pop和push)。

list也有其自己的缺点:

因为其每个节点有两个指针域,导致占用空间较大;
list不支持[]操作符和at方法。

注:

不是list不能实现[]和at,而是设计者认为list在这方面表现的很不好,随机访问也不应该是list的用武之地,所以不这么实现,但不代表着不能实现。

对于list,清除所有的元素需要依次遍历,效率很低(如果是vector,因为是一整块内存,可以很方便地进行操作)。


三、deque

deque=double-end-queue,意即双端队列。

可以将deque看成是list和vector的结合。

deque不仅支持随机访问[]以及at(效率接近于vector),而且在插入和删除方面也表现出很不错的性能(尤其是在首位进行插入删除,效率接近于list)。

deque还可以类似list那样在两端进行pop和push。

猜测:

deque可能是下面的存储结构:

这里写图片描述

每几个元素时连续的一个内存块,而每个内存块之间有指针链接起来。

当随机访问时使用一个分段函数可以相对方便地计算出来地址(当然没有vector那样方便啦,只是比起list来说好很多了);

当在首位进行插入删除时有接近于list的性能表现。

综上三点,得出以下结论:

1.如果有大量的随机访问,而插入和删除操作较少,应该使用vector;

2.如果有大量的插入和删除,而随机访问较少,应该使用list;

3.如果既有很多的插入和删除,又有很多的随机访问,那么deque是个不错的选择。

另外一点,如果在不知道内存具体需求的时候,一般使用deque要比vector性能好一些。

恩,暂时就这些吧,后续有测试再添加过来吧~

参考来源:

1.http://blog.csdn.net/gogokongyin/article/details/51178378

2.http://blog.csdn.net/bruceyang2009lzu/article/details/8525451

3.http://www.cnblogs.com/Billy-rao/p/3808259.html

4.http://www.cppblog.com/sailing/articles/161659.html

0 0
原创粉丝点击