容器
容器分为顺序容器和关联容器。顺序容器连续存储,支持随机访问。
一、顺序容器
1. array
即 数组,大小固定,元素按照内存地址线性排列。
2.vector
动态分配空间,使用“预分配空间策略”。
vector 在元素访问上效率最高,在尾部增删元素的效率也相对最高。如果调用者有在尾部以外的地方增删元素的需求,vector 则不如其它容器。
3.deque
double-ended-queue, 双端队列,顾名思义,首尾两端都可以增删的顺序容器。
从底层理解,vector使用的是单一的array, deque 会使用多个离散的array来组织数据,所以它不能保证存储区域是连续的,所以用指向元素的普通指针做 ++、--操作是很危险的。
并且,它在重新分配空间时,只用新增或者释放两端的存储块,比vector快。
缺点:deque 并不适合遍历!因为每次访问元素时,deque 底层都要检查是否触达了内存片段的边界,造成了额外的开销!
4.forward_list
底层是一个单链表,只能单向遍历,但是占用的内存比list小,插入和删除效率也高。
5.list
list的底层是双链表,它的元素不是在连续空间存储的,而是由指针指向后续结点。
一个链表结点包括一个数据域和一个存放后续结点地址的指针。双链表结点中有两个指针,一个指向前驱动结点,一个指向后续结点。
不支持随机访问,但是插入和删除非常快。
6.queue
普通队列,支持先进先出。
采用适配器模式。Adapter 模式的目的是将第三方库提供的接口做一个封装和转化,使其适配自己工程中预留的接口,或者适应自己工程的调用风格。换句话说,Adapter 模式的目的是将被调用类(如第三方库)的接口转化为希望的接口。
7.priority_queue
优先队列,也是容器适配器,需要指定底层容器才能实例化.
原理是类似一个大顶堆,最大的元素始终位于堆顶部。
8.栈
二、关联容器
1.map
元素类型是key 和 value。底层是红黑树来讲所有元素按照key的相对大小进行排序,红黑树是一种自平衡的二叉排序树,不过,与平衡树不同的是,红黑树在插入、删除等操作,不会像平衡树那样,频繁着破坏红黑树的规则,所以不需要频繁着调整。
map可以用key做下标,map的下标运算符[ ]将关键码作为下标去执行查找,如果关键码不存在,则插入一个具有该关键码和mapped_type类型默认值的元素至map中,因此下标运算符[ ]在map应用中需要慎用。
2.multimap
3.unordered_map
像map 一样,也是以键值对进行存储元素,但是其他的完全不一样。
它的底层是用哈希表来组织数据结构的,所以它直接访问元素比较快,但是它不支持排序,用迭代器访问比较慢。
通常 map 增删元素的效率更高,unordered_map 访问元素的效率更高,并且占用的内存也更高。
unordered_map 更适用于增删操作不多,但需要频繁访问,且内存资源充足的场合。
4.set
set中的key和value是一个,set中的元素是唯一的,它的底层也是红黑树,所以 set 中的元素也是严格弱序(strict weak ordering)排序的,因此支持用迭代器做范围访问(迭代器自加自减)。
5.multiset