标准库定义了顺序容器和关联容器,顺序容器内的元素按其位置存储和访问,关联容器内的元素按其键(key)排序。容器只定义了少量的操作,其他大量的操作是通过算法库实现,比如说排序和查找。算法库中的算法没有为每种容器类型设计特定的操作,而是定义了一组泛型算法,通过迭代器在容器上实施。
1、顺序容器
顺序容器主要有vector,list,deque;顺序容器适配器主要有stack,queue,priority_queue。
vector和list的区别:vector是可扩展的数组,比array的优越性在于可扩展,但和array一样在内存里是一块连续的区域,支持快速的随机访问。list是双向链表结构,支持快速的插入和删除工作。正因为vector的内存连续,一方面在扩展时会预留将近一倍的空间,当预留空间不足时vector会采取“重新配置,复制和释放”的工作,影响效率。但是push_back在vector尾部添加元素的方式还是非常高效,从技术上说在原来为空的vector容器上n次调用push_back函数,从而创建拥有n个元素的vector容器,其执行时间永远不能超过n的常量倍,所以一般也是通过push_back来添加元素,并通过pop_back释放尾部元素。另一方面,如果在vector内部使用erase函数和insert函数,则在变化位置之后的元素需要集体往前移,所以不建议erase在vector上面使用;而同理push_front和pop_front两个函数则不能应用在vector头部,只能应用在list和deque上面。
deque是双端队列,在内存中采取“分段存储,整体维护”的方式。从deque队列的首尾两端插入和删除元素都非常快,但是中间插入和删除的代价就会大很多。deque支持对所有元素的随机访问,但因为分段存储的原因,其中也涉及到指针的跳转(整体有个map表维护分段连续内存的起始地址),所以随机访问也是假象,但是效率确实非常高。deque是顺序适配器的幕后功臣,对deque适当的修改就能成为stack,queue或是priority_queue。
2、关联容器
关联容器有map/multimap,set/multiset,hash_set/hash_map。map和set的实现是红黑树,插入、查询和删除效率非常高(logh)。而hash_set和hash_map的幕后工程是hashtable(哈希表)。