vector又称为向量数组,他是为了解决程序中定义的数组是
不能动态改变大小这个缺点而出现的。
通常程序实现是在类建立的时候同时建立一个定长数组,
随着数据不断被写入,一旦数组被填满,则从新开辟一块更大的内存区,
把原有的数据复制到新的内存区,抛弃原有的内存,如此反复。
因为程序自动管理数组的增加,对于咱们程序员来讲确实轻松了很多,
只管把数据往里面插就好了,固然把物理内存和虚拟内存插爆掉了
就是操做系统来找你麻烦了:-)
vector因为数组的增加只能向前,因此也只提供了后端插入和后端删除,
也就是push_back和pop_back。固然在前端和中间要操做数据也是能够的,
用insert和erase,可是前端和中间对数据进行操做必然会引发数据块的移动,
这对性能影响是很是大的。
对于全部数组来讲,最大的优点就是随机访问的能力。
在vector中,提供了at和[]运算符这两个方法来进行随机访问。
因为每一个数据大小相同,而且无间隔地排列在内存中,
因此要对某一个数据操做,只须要用一个表达式就能直接计算出地址:
address = base + index * datasize
一样,对vector进行内存开辟,初始化,清除都是不须要花大力气的,
从头至尾都只有一块内存。 前端
有黑必有白,世界万物都是成对出现的。
链表对于数组来讲就是相反的存在。
数组自己是没有动态增加能力的(程序中也必须从新开辟内存来实现),
而链表强悍的就是动态增加和删除的能力。
但对于数组强悍的随机访问能力来讲的话,链表却很弱。
list是一个双向链表的实现。
为了提供双向遍历的能力,list要比通常的数据单元多出两个指向先后的指针。
这也是没办法的,毕竟如今的PC内存结构就是一个大数组,
链表要在不一样的环境中实现本身的功能就须要花更多空间。
list提供了push_back,push_front,pop_back,pop_front四个方法
来方便操做list的两端数据的增长和删除,不过少了vector的at和[]运算符的
随机访问数据的方法。并非不能实现,而是list的设计者
并不想让list去作那些事情,由于他们会作得很是差劲。
对于list来讲,清除容器内全部的元素是一件苦力活,
由于全部数据单元的内存都不连续,list只有一个一个遍从来删除。 程序员
黑与白,处于这两个极端之间的就是使人愉悦的彩色了。
deque做为vector和list的结合体,确实有着不凡的实力。
STL的deque的实现没有怎么去看过,不过根据我本身的猜想,
应该是把数组分段化,在分段的数组上添加指针来把全部段连在一块儿,
最终成为一个大的数组。
deque和list同样,提供了push_back,push_front,
pop_back,pop_front四个方法。能够想象,若是要对deque的两端进行操做,
也就是要对第一段和最后一段的定长数组进行从新分配内存区,
因为分过段的数组很小,从新分配的开销也就不会很大。
deque也和vector同样,提供了at和[]运算符的方法。
要计算出某个数据的地址的话,虽然要比vector麻烦一点,
但效率要比list高多了。
首先和list同样进行遍历,每次遍历的时候累积每段数组的大小,
当遍历到某个段,并且baseN <= index < baseN + baseN_length的时候,
经过address = baseN + baseN_index就能计算出地址
因为分过段的后链表的长度也不是很长,因此遍历对于
总体性能的影响就微乎其微了。
看起来deque很无敌吧,不过deque和希腊神话的阿吉里斯同样,
再怎么强大也是有本身的弱点的,以后的测试数据中就能看到了。 后端