C++笔记(2):STL容器vector、list、deque、map、set、hashmap

STL容器vector、list、deque、map、set、hashmap

(1) vector 向量

相当于一个数组,占用一块连续的内存空间。

  • 优点
  1. 可以不指定数组大小。即可以像数组一样操作,且具有动态长度,主要体现在push_back()pop_back()
  2. 随机访问方便。支持下标操作符[]和.at();
  3. 节省空间。每个位置仅保存值对象,没有其他内容(指针等)。
  • 缺点
  1. 内部的插入和删除操作效率低。可能会涉及到该位置之后的一系列内容的移动;
  2. 只能在vector的最后进行push和pop操作,不能在vector的头部进行push和pop操作;
  3. 当动态添加的数据超过vector当前分配的容量capacity时,需要重新申请一块更大的内存,并将vector的内容拷贝到新的内存,释放原内存。
  • 适用场景
    如果需要高效的随机存取,不在乎插入/删除的效率或者插入/删除的操作极少时,可使用vector。

(2) list 双向链表

list每个节点都由一个value,一个前驱指针和一个后驱指针组成。

  • 优点
  1. 不需要使用连续的内存;
  2. 可以在内部进行方便的插入和删除操作;
  3. 可以在两端进行push和pop。
  • 缺点
  1. 不支持随机访问,即不支持下标操作符[]和.at();
  2. 相对vector占用更多的内存。因为多了前驱指针和后驱指针。
  • 适用场景
    如果需要大量的插入和删除操作,不在乎随机存取,可使用list。

(3) deque 双端队列

deque造成连续内存的假象。deque是由一系列连续内存组成,并不是一个,当走到一段内存的尾端的时候,会自动跳到下一段,所以支持迭代器++操作。deque在功能上合并了vector和list。

  • 优点
  1. 支持随机访问。即支持下标操作符[]和.at();
  2. 可以在内部进行方便的插入和删除操作;
  3. 可在两端进行push和pop。
  • 缺点
  1. 占用更多的内存。
  • 适用场景
    如果既需要随机存取,也需要关心内部的插入和删除操作,可使用deque。

(4) map/multimap 一对一关联

内部实现为红黑树,存储的内容为key-value对,每个key只对应一个value时使用map,对应多个value时使用multimap。

  • 优点
  1. 具有自动排序的功能,根据key值进行排序;
  2. 插入和删除比vector快,但比list慢;
  3. 可以使用下表操作符[]来检索数据(multimap不支持该功能)。
  • 缺点
  1. 每次插入值时,需要调整红黑树;
  2. 随机存取比vector慢比list快,查找的复杂度为 O ( l o g ( n ) ) O(log(n)) O(log(n)).
  • 适用场景
    如果需要用存储数据字典,并需要方便地根据key找到value,一对一的情况可使用map,一对多的情况应使用multimap。

(5) set/multiset 集合

对于相同的元素,set只会存储一遍,因为set中不会包含重复的元素,而multiset则可以包含重复元素,因此会存储多遍。

  • 优点
  1. 便于查找。set内部是使用红黑树实现,会自动排序。
  • 适用场景
    如果需要查找某个元素是否存在于一个集合中,唯一存在可使用set,不唯一存在可使用multiset。

(6) hashmap 散列表

通过将关键码值映射到hash表中的一个位置来存储和访问。元素的排列是无序的。这种数据结构在插入、删除、搜索等操作上通常具有"常数时间"的表现。

  • 优点
  1. 查找效率高,查找的时间复杂度为 O ( 1 ) O(1) O(1)。通常情况下,查找速度比map快(map的查找时间为 O ( l o g ( n ) ) O(log(n)) O(log(n)))。当然常数并不一定就比log(n)小,还需要考虑hash函数的消耗。
  • 缺点
  1. 需要占用较多的内存;
  2. 构造速度慢;
  3. 可能出现hash碰撞。(解决思路:链地址法、开放地址法)
  • 适用场景
    如果需要较高的查找效率,且元素达到一定数量级,不太关心内存占用时,可使用hashmap。

你可能感兴趣的:(C++笔记)