前言
STL(Standard Template Library),即标准模板库,是一个高效的C++程序库,包含了诸多常用的基本数据结构和基本算法,提供了一组表示容器、迭代器、函数对象和算法的模板。从逻辑层次来看,在STL中体现了泛型化程序设计的思想(generic programming)。大部分基本算法被抽象、被泛化,独立于与之对应的数据结构,用于以相同或相近的方式处理各种不同情形。从实现层次看,以一种类型参数化(type parameterized)的方式实现的,基于模板(template)。
STL的基本观念即将数据和操作分离,数据由容器进行管理,操作则由算法进行,而迭代器将容器和算法进行关联,使之可以交互运作。STL能够构造各种容器(vector、deque、list等)和执行各种操作(搜索、排序、随机排序等)。
- 容器:是数据存储上的一种对象类型,存储其他对象的对象。它可以持有其他对象或指向其他对象的指针,被存储的对象必须是同一类型。换言之,容器是存储其他对象的对象,并且还有处理其他对象的方法。STL中提供了七种基本容器类型。
- 迭代器:是用来遍历容器的对象,与能够遍历数组的指针类似,是广义的指针。
- 函数对象:是类似于函数的对象,可以是类对象或各函数指针。
- 算法:处理对象集合中元素,完成特定任务的方法,是泛型算法(generic algorithm)。
序列式容器
序列式容器(sequential container):元素的位置与插入时间和地点有关,与元素值无关。可以通过元素在序列中的位置访问对应的元素。STL提供了vector、deque、list,而string和array也是序列式容器。
名称 | 特点 |
---|---|
array(数组) | 可以连续存储相同类型数据的定长数组,只能修改元素值 |
vector(向量) | 可以连续存储相同类型数据的动态数组,可以增加或删减元素。在尾部增删元素效率最高(时间复杂度:O(1)),在其他位置插入或删除元素效率较差(O(n))。 当分配空间不够时,会申请更大的内存空间,将原数据拷贝到新的内存块中,释放原内存空间。[连续线性空间] |
deque (双端队列) | 是一种拥有队列和栈特性的结构的数据结构。类似于Vector,在头尾增删元素均为O(1),其余位置为O(n)。 由于采用多个连续的存储块,然后用一个map(映射)保存对这些存储块和顺序的跟踪。即动态地以分段连续空间组合而成,因此没有容量的capacity的概念。[连续线性空间(兼顾了list和vector的特点。用map映射,非连续的联合了连续空间)] |
list (链表) | 线性链表结构,数据由节点构成,每个结点包含一个前驱和一个后继指针,以及一个信息快(存储数据)。[非连续内存空间] |
关联式容器
关联式容器(Associative container):容器内元素已经有序,元素位置取决于特定的排序准则以及元素值,和插入次序无关。容器内存储结构为<key>键值或<key,value>键值对,类似于python的字典,因此数据检索时效率较高。map、set、multimap、multiset均是树形结构,并以平衡搜索树(红黑树)作为底层实现,容器中的元素有序排列。(C++11中,增加了4中无序关联式容器unordered_set、unordered_multiset、unordered_map、unordered_multimap,底层基于哈希表结构,旨在提高增删元素的速度和查找算法的效率)
名称 | 特点 |
---|---|
set(集合) | 按key比较排序存储元素(容器内仅保存键值,且key键值不重复) |
multiset(多重集合) | 按照key比较排序存储由键值key和值value组合而成的元素 (容器内保存键值对,且key键值不重复) |
map (映射) | 与set相似,但key键值可重复 |
multimap(多重映射) | 与map相似,但key键值可重复 |
容器适配器
容器适配器(container adapter):容器是对类模板的封装,而容器适配器是对容器的一种再封装。不同的容器适配器提供不同的函数,使容器的功能得到全新的特定的扩展。(换言之,将容器提供的接口转换为容器适配器的接口,但容器适配器不支持迭代器和算法,相当于为了利用容器适配器的特性,而阉割了容器的功能)C++提供了三种容器适配器:stack、queue和priority_queue。
名称 | 特点 |
---|---|
stack(栈) | (后进先出)默认基于deque实现,可基于vector、list、deque |
queue(队列) | (FIFO,先进先出)默认基于deque实现,要求基础容器提供push_front操作,因此只能基于list、deque |
priority_queue(优先级队列) | 默认基于vector实现,要求随机访问,因此只能基于vector、deque |