容器,是STL中很重要的一部分,是容纳特定类型对象的集合,因此容器中的对象必须是同一个类型,而且必须是可拷贝构造和可赋值的。STL为容器的遍历提供了迭代器,还提供了很多算法,如排序,查找等。
也可以把容器理解为我们学过的数据结构,我们学过的数据有array(数组),list(链表),stack(栈),set(集合),tree(树) ··· 这些数据结构分为序列式和关联式,所以容器就分为序列式和关联式。
序列式容器
将一组有相同类型T的对象,以严格的线性的方式组织在一起。
vector
它的数据结构是一个线性的连续空间,就像顺序表,其中有两个迭代器start和finish分别指向已使用空间的首部和尾部,迭代器end_of_storage指向分配的连续空间的尾部。如图:
为了节省空间,在分配内存的时候并不是一次性分配一个很大的内存空间,采用的策略是先分配一小块内存空间,不够了,再增容,也就是动态增容。增容的时候要先申请一个比原空间大二倍的空间,然后把原来的数据拷贝到新开的空间里,最后释放原空间。但是这也有可能造成迭代器失效的问题,指向原空间的迭代器会失效。
vector的一些常见接口:
有常见的插入,删除等操作,重载了[]可以使它像数组一样取到数据,但是一般不用operator[],因为没有边界检查,推荐使用at(),如果超过了范围会抛出异常。
list
STL中的list是一个环形的双向链表,并且带头结点。
list的接口:
deque
双端队列,接口和vector类似。
关联式容器
提供一个key值实现对元素的随机访问,并且key是有序的
map
map底层是用红黑树实现的,所有的结点都是Pair型的,第一个元素是key值,第二个元素是value,建立红黑树是根据key值。可以通过迭代器来改变value的值,但不能改变key值,否则会破坏它的结构。
multimap:和map的用法相同,与map的区别是允许key值重复。
set
底层的实现也是红黑树,与map的区别是没有key值和value值之分,不能通过迭代器来改变值,因此底层的iterator被定义为const_iterator.
multiset:与set的区别是值可以重复。