C++ STL标准库容器 概览

前言

本文对C++中的STL标准库容器进行概览,作为笔者平时的学习笔记,以兹备忘。同时,本文作为一个目录,接下来对常用容器,比如vector,map等的 具体介绍的博文将会由本文进行索引。


C++的标准容器库中提供了一系列的容器模版,可以作为日常工作生产中的数据结构使用,以此减少了程序员很多去造轮子的工作量。容器(container),顾名思义,是一种按照某种特性,用于储存某种类型数据的一种数据结构,其中通常还包含了若干对这种数据结构进行运算的算法,比如出栈,入栈,排列等等,C++将整个数据容器视为一种数据容器类,方便程序员的使用。通常来说,C++标准容器可以分为以下四大类型:

  1. 序列容器(Sequence containers)
  2. 序列容器适配器 (Sequence container adapters)
  3. 关联容器 (Associative containers)
  4. 无序关联容器 (Unordered associative containers)

我们分别简单介绍这四大类型容器中的常用的容器模版。

序列容器

序列容器以一种线性的方式去储存相同类型的数据类型的一系列数据。包括:

  1. array, 静态的,连续数组,类似于C语言中的数组。
  2. vector,动态的,连续数组,其长度可以随着插入或者移除的元素而变化。
  3. forward_list,单向链表
  4. list,双向链表
  5. deque,一种双端队列,元素可以在该队列的头部或者尾部插入和弹出。(不能在中间插入,只能在两端插入)

序列容器适配器

容器适配器是一种容器类的特殊类型。他们自己并不是完全的容器类,其依赖于对其他容器类型(比如vector,list,deque)进行一层更高层级的语法包裹,封装起来(wrapper),以达到其设计的功能。容器适配器可以对潜在的容器类型进行压缩,限制该被包裹的容器的某些用户接口行为。
我们以std:stack为例子,栈结构的特点是LIFO,也就是Last In First Out,因此必须限制某些用户接口,只能让容器数据从某个方向有规律有顺序地弹出或者插入。我们并不需要重新对这个stack数据结构进行编码,只需要在某些已经实现了特定功能的数据结构,比如deque中,进行限制接口即可了。我们会发现,std:stack的声明如:

template<
    class T,
    class Container = std::deque<T>
> class stack;

注意到这个stack容器默认情况下是对std:deque<T>的一种封装,包裹。你也可以指定特定的容器,取代这里的deque

标准容器中的容器适配器有:

  1. stack,提供LIFO的数据结构
  2. queue,提供了FIFO的数据结构
  3. priority_queue,提供了一个优先队列,其允许在该队列中以常数时间复杂度去检索最大的元素(默认情况下)

关联容器

关联容器提供了一种排序后的数据结构,配合对keys的检索,可以提供一个快速的检索,时间复杂度为O(log(n))\mathcal{O}(\log(n))
在STL的关联容器中,其按照检索的keys,可分为两大类:A. 每个元素都只有唯一的key; B. 可以用相同的key检索多个元素。

  • 唯一key:
  1. set ,唯一key检索,根据key的某些特性进行排序(比如数值大小,首字母顺序等)
  2. mapkey-value对的集合,也是根据key的某些特性进行排序(比如数值大小,首字母顺序等)
    -> 这两者通常都是通过红黑树进行实现的。
  • 同一个key检索多个元素:
    1. multiset,类似于set,只不过可能有重复的key
    2. multimap,类似于map,只不过可能有重复key

我们以set为例,观察下其模版原型:

template<
    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>
> class set;

我们发现,我们可以指定其排列的规则,默认是std:less

无序关联容器

无序关联容器,类似于关联容器,不过其是无序的,不需要对元素进行排序,通常根据hash进行索引。在最差的情况下,其时间复杂度是O(n)\mathcal{O}(n),不过大部分时候都远比线性操作要快得多,可以视为O(1)\mathcal{O}(1),即是在常数时间内就可以对元素进行检索。无序关联容器有:

  • key是唯一的:
    1. unordered_set,类似于set,只不过是无序的。
    2. unordered_map,类似于map,只不过是无序的。
  • key不唯一:
  1. unordered_multiset,类似于multiset,只不过是无序的。
  2. unordered_multimap,类似于multimap,只不过是无序的。

unordered_set的模版原型为例子,有:

template<
    class Key,
    class Hash = std::hash<Key>,
    class KeyEqual = std::equal_to<Key>,
    class Allocator = std::allocator<Key>
> class unordered_set;

Reference

[1]. https://embeddedartistry.com/blog/2017/08/02/an-overview-of-c-stl-containers/

posted @ 2020-02-05 23:08  FesianXu  阅读(121)  评论(0编辑  收藏  举报