C++ STL容器 内容详解

文章目录

  • C++ STL容器
    • 序列容器
      • array数组容器
      • vector向量容器
      • deque双端队列容器
      • list链表容器
      • forward_list正向链表容器
    • 关联容器
      • 排序容器
        • set集合容器
        • multiset多重集合容器
        • map映射容器
        • multimap多重映射容器
      • 哈希容器(无序关联容器、无序容器)
        • unordered_set哈希集合
        • unordered_multiset哈希多重集合
        • unordered_map哈希映射
        • unordered_multimap哈希多重映射

C++ STL容器

 简单来说,容器就是一些模板类的集合,但和普通模板类不同的是,容器中封装的是组织数据的方法(也就是数据结构)。

 STL提供三类标准容器:序列容器排序容器哈希容器,其中后两类容器也称为关联容器



序列容器

 所谓序列容器,即以线性排列(类似普通数组的存储方式)来存储某一指定类型的数据。之所以被称为序列容器,是因为元素在容器中的位置与元素的值无关,即容器不是排序的,该类容器并不会自动对存储的元素按照值的大小进行排序。也就是说,将元素插入容器时,指定在什么位置,元素就会位于什么位置。

 序列容器主要包括:

array数组容器

array:表示可以存储N个T类型的元素,是C++本身提供的一种容器。
此类容器一旦建立,其长度就是固定不变的,这意味着不能增加或删除元素,只能改变某个元素的值。
C++ STL容器 内容详解_第1张图片

vector向量容器

vector< T >:用来存放T类型的元素,是一个长度可变的序列容器,即在存储空间不足时,会自动申请更多的内存。
使用此容器,在尾部增加或删除元素的效率最高(O(1)),在其它位置插入或删除元素的效率较差(O(n),其中n是容器中元素的个数)。
C++ STL容器 内容详解_第2张图片

deque双端队列容器

deque< T >:和vector非常相似,区别在于使用该容器不仅尾部插入和删除元素高效,在头部插入或删除元素也同样高效,时间复杂度均为O(1),但是在容器中某一位置插入或删除元素的时间复杂度仍为O(n)。
C++ STL容器 内容详解_第3张图片

list链表容器

list< T >:是一个长度可变、由T类型元素组成的序列,它以双向链表的形式组织元素,在这个序列的任何地方都可以高效的增加或删除元素(O(1)),但访问容器中任意元素的速度要比前三种容器慢,这是因为list< T >必须从第一个元素或最后一个元素开始访问,需要沿着链表移动,直到到达想要访问的元素。
C++ STL容器 内容详解_第4张图片

forward_list正向链表容器

forward_list< T >:和list容器非常类似,只不过它以单链表的形式组织元素,它内部的元素只能从第一个元素开始访问,是一类比链表容器快、更节省内存的容器。
C++ STL容器 内容详解_第5张图片


关联容器

关联式容器在存储元素值的同时,还会为各元素额外再配备一个值,又称为“键”,其本质也是一个C++基础数据类型或自定义类型的元素,它的功能是在使用关联式容器的过程中,如果已知目标元素的键的值,则直接通过该键就可以找到目标元素, 而无需通过遍历整个容器的方式。
也就是说,使用关联式容器存储的元素,都是一个个的键值对(),这是和序列式容器最大的不同。除此之外,使用关联式存储的元素,默认会根据各元素的键值的大小做升序排序。



排序容器

 排序容器中的元素默认是由小到大顺序排好的,即便是插入元素,元素也会插入到适当位置。所以关联容器在查找时具有非常好的性能。
 排序容器主要包括:

set集合容器

定义在< set >头文件中,使用该容器存储的数据,各个元素的键和值完全相同,且各个元素的值不能重复(保证了各元素键的唯一性)。该容器会自动根据各个元素的键(其实也就是元素的值)的大小进行升序排序(调用std::less< T >)。

multiset多重集合容器

定义在头文件中,和set容器唯一的不同在于,multiset容器中存储元素的值可以重复(一旦值重复,则意味着键也是重复的)。

map映射容器

定义在< map >头文件中,使用该容器存储的数据,其各个元素的键必须是唯一的,不能重复,该容器会根据各元素键的大小,默认进行升序排序(调用std::less< T >)。

multimap多重映射容器

定义在< map >头文件中,和map容器唯一的不同在于,multimap容器中存储元素的键可以重复。


哈希容器(无序关联容器、无序容器)

 哈希容器中的元素是未排序的,元素的位置由哈希函数确定
 和关联式容器一样,无序容器也使用键值对(pair类型)的方式存储数据
 但是,关联式容器和无序容器之间有本质上的不同:关联式容器的底层实现采用的树存储结构,更确切的说是红黑树结构;无序容器的底层实现采用的是哈希表的存储结构(C++底层采用哈希表实现无序容器时,会将数据存储到一整块连续的内存空间中,并且当数据存储位置发生冲突时,采用“开链法”解决)。

基于底层实现采用了不同的数据结构,因此和关联式容器相比,无序容器具有以下两个特点

  1. 无序容器内部存储的键值对是无序的,各键值对的存储位置取决于键值对中的键。
  2. 和关联式容器相比,无序容器擅长通过指定键查找对应的值(O(1)),但对于使用迭代器遍历容器中存储的元素,无序容器的执行效率则不如关联式容器。

C++ 11中新添加4中关联式容器:

unordered_set哈希集合

不再以键值对的形式存储数据,而是直接存储数据元素本身(也可以理解为,该容器存储的全部都是键key和值value相等的键值对,正因为它们相等,因此只存储value即可)。另外,该容器存储的元素不能重复,且容器内部存储的元素也是无序的。

unordered_multiset哈希多重集合

和unordered_set唯一的区别在于,该容器允许存储值相同的元素。

unordered_map哈希映射

存储键值对类型的元素,其中各个键值对的键不允许重复,且该容器中存储的键值对是无序的。

unordered_multimap哈希多重映射

和unordered_map唯一的区别在于,该容器允许存储多个键相同的键值对

 很容易发现,以上4种无序容器的名称,是前面4种关联式容器名称的基础上添加了"unordered_",以 map 和 unordered_map 为例,其实它们之间只有一个区别:即 map 容器内存会对存储的键值对进行排序,而 unordered_map 不会。

 无序容器其实就是在已提供的4种关联式容器的基础上,又新增了各自的"unordered"版本,提高了查找指定元素的效率。

 既然无序容器和之前所学的关联式容器类似,那么在实际使用中应该选哪种容器呢?
 总的来说,实际场景中如果涉及大量遍历容器的操作,建议首选关联式容器;反之,如果更多的操作是通过键获取对应的值,则应首选无序容器

本文中链接的内容持续更新中。。。

你可能感兴趣的:(C++,STL,c++,数据结构,stl)