STL序列容器总结

STL 的各种容器:

STL序列容器总结_第1张图片

 

一、vector

vector 的数据安排及操作方式,与 array 非常相似,两者的区别在于,array 是静态空间,一旦配置不能改变,vector 是动态空间。

1. vector 的数据结构

STL序列容器总结_第2张图片

通过这个三个迭代器可计算得到容器内元素个数和容器当前容量。

2. vector 的空间分配与容量

增加新元素时,若超过容器当前的容量,则容量会扩充至两倍,若仍不足则扩张至足够大的容量。只要没有操作需要超出 vector 的容量,就不能重新分配内存空间。一旦引起空间重新配置,指向原 vector 的所有迭代器就都失效了。

扩张空间并不是简单地在原空间之后新增空间,而是一个“重新配置新空间、元素移动、释放原空间”的复杂过程。

size() 操作获取容器内元素的个数,capacity() 操作获取容器当前的最大容量,空 vector 的size和capacity都是0。可以通过 reserve(n) 操作分配至少n个元素的内存空间(可能更大),当需要容量小于当前容量时,容器不会退回内存空间。

对于 vector 的任何操作,只要引起空间重新配置,指向原 vector 的所有迭代器就都失效了。

3. vector 的元素操作

pop_back 即删除尾端元素;erase 可清除某个位置上的元素或某个区间内的元素;clear 即 erase(begin(), end())。

二、list

1. list 基本性质

  • 相较于 vector 的连续线性空间,list 每次插入或删除一个元素,就配置或释放一个元素空间。
  • STL中的 list 是一个双向链表,而且还是环状双向链表。
  • list 任意元素的插入和移除操作都是常数时间。
  • 插入操作和接合操作都不会造成 list 原有迭代器失效。
  • 删除操作仅指向被删除元素的迭代器失效。
  • STL 提供了一个单向链表(single linked list)slist。

2. list 的元素操作

list 内部提供一个迁移操作(transfer),将某连续范围的元素迁移到某个特定位置之前,技术上是节点间的指针移动。该操作为复杂操作如 splice、sort、merge 奠定基础。

STL序列容器总结_第3张图片

  • push_front / push_back,插入一个节点作为头节点 / 尾节点。
  • pop_front / pop_back,移除头节点 / 尾节点。
  • erase,移除迭代器所指结点。
  • remove,移除数值为 value 的所有元素。
  • unique,移除数值相同且连续的元素,重复元素剩一个。
  • splice,将某个连续范围的元素从一个list移动到另一个(或同一个)list的某个位置。
  • merge,合并两个 list,两个 lists 必须是经过递增排序的。
  • reverse,将 list 的内容反转。
  • sort,list 不能使用STL算法 sort,必须使用自己的成员函数 sort。

三、deque

1. 基本性质

  • 相对于 vector 单向开口的连续线性空间,deque 则是一种双向开口的连续线性空间。即可在头尾两端分别做元素的插入和删除操作。
  • 与 vector 的最大差异,一是 deque 允许常数时间内在头部进行元素的插入或移除操作;二是 deque 没有容量的概念,是动态地以分段连续空间组合而成,随时可以增加一段新的空间并连接起来。

2. deque 如何实现分段连续空间的中央控制。

deque 采用一块所谓的 map(非STL的map容器)作为主控,map 是一块连续空间,其中的每个元素都是指针,指向另一段连续线性空间,称为缓冲区,缓冲区才是真正的 deque 储存空间主体。当 map 使用率满载时,就需要再找一块更大的空间来作为 map。STL 允许指定缓冲区的大小,默认值0表示将使用512 bytes 缓冲区。

3. deque 的数据结构

除了要维护一个指向 map 的指针,还需要维护 start 和 finish 两个迭代器,分别指向第一缓冲区的第一个元素和最后缓冲区的最后一个元素(的下一位置),此外还需要记住 map 的大小 map_size。一旦 map 所提供的节点不足,就必须重新配置更大的一块 map。

四、stack

1. 基本性质

  • stack 只有一个出口,是一种先进后出的数据结构。
  • STL 中以 deque 为 stack 底部结构。具有这种“修改某物接口,形成另一种风貌”之性质者,称为 adapter 配接器。故 STL stack 往往不归为 container 容器,而归为 container adapter。
  • stack 没有迭代器,不提供走访功能。
  • 除了 deque 之外,以 list 为底层结构也可以形成一个 stack。

2. 元素操作

empty、size、top、push、pop。

STL序列容器总结_第4张图片

五、queue

1. 基本性质

  • queue 允许最底端可以加入、最顶端可以取出。
  • STL 中以 deque 为底层结构,封闭其底端的出口和顶端的入口,形成 queue。
  • queue 没有迭代器,不提供遍历功能。
  • queue 同样可以以 list 为底部结构实现。
  • STL queue 往往不归为 container 容器,而归为 container adapter。

六、heap

1. 基本性质

  • heap 可分为 max_heap 和 min_heap,前者每个节点的键值都大于等于其子节点键值,后者每个节点的键值都小于等于其子节点键值。
  • 以数组表述树的方式,称为隐式表述法。heap 需要动态改变大小,故以 vector 代替数组实现。
  • STL 提供的是 max_heap。

2. heap 算法

(1)push_heap,新加入的元素首先放在最下一层作为叶节点,然后执行一个上溯程序,将新节点与其父节点比较,若键值比父节点大,就对换位置,一直上溯至不需要对换或到根节点为止。

(2)pop_heap,pop 操作取走根节点(其实是移至 vector 的最后一个元素位置)之后,原来该位置的元素填入根节点,然后将其与两个子节点进行比较,与较大子节点对换位置,如此一直下溯,直到该元素大于两个叶节点或下溯至叶节点为止。

(3)sort_heap,每次 pop_heap 可获得 heap 中键值最大元素,持续对整个 heap 做 pop_heap 操作,每次将操作范围从后向前缩减一个元素,最终便得到一个递增序列。排序过后,原来的 heap 已不再是合法的 heap 了。

(4)make_heap,将一段现有的数据转化为一个 heap。

七、priority_queue

1. 基本性质

  • priority_queue,缺省(默认)情况下以一个 max_heap 为底层,后者以一个 vector 表现的完全二叉树实现。
  • 只允许在底端加入元素,在顶端取出元素。
  • 带有权值观念,其内的元素并非按照进入的次序排列,依照元素的权值排列。
  • STL priority_queue 往往不归为 container 容器,而归为 container adapter。

2. priority_queue 提供 empty、size、top、push、pop 等算法。

 

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