STL六大组件简介

STL中的六大组件包括:容器、容器适配器、算法、迭代器、仿函数、空间配置器。
STL六大组件简介_第1张图片
STL六大组件的相互关系:容器通过空间配置器取得数据存储空间;算法通过迭代器存取数据存储容器内容;仿函数可以协助算法完成不同的策略变化;空间适配器可以修饰或套接仿函数。

容器

下面我们总结容器这个组件。
STL六大组件简介_第2张图片
纠错:multimap、multiset关键字可以重复。

1.vector

优点是访问元素效率高,因为是连续空间,所以内存使用率高,缓存使用率也高。缺点是中间位置插入和删除不方便,效率低。

2.list

优点是中间位置进行插入、删除方便,但访问效率不高。缺点是随机访问的效率低,需要遍历O(N)的时间复杂度。

3.双端队列的原理

所谓的deque是”double ended queue”的缩写,双端队列不论在尾部或头部插入元素,都十分迅速。而在中间插入元素则会比较费时,因为必须移动中间其他的元素。双端队列是一种随机访问的数据类型,提供了在序列两端快速插入和删除操作的功能,它可以在需要的时候改变自身大小,完成了标准的C++数据结构中队列的所有功能。
STL六大组件简介_第3张图片
双端队列是一种优化了的对序列两端元素进行添加和删除的基本序列容器,通常由一些独立的区块组成。开辟一段固定大小的连续空间,从中间开始插入或者删除元素,队头插入一个元素,first指针–,直到减为0,下一次再继续开辟一段相同大小的空间,存入元素。在队尾插入元素的原理也是一样的,插入一个元素,end++,直到加到最后一个位置,下一次开辟一段相同大小的空间,存入元素。这些连续空间由一个一维数组维护,存放每块空间的地址,也是先从中间开始存放。

了解了双端队列的存储结构吗,那么,如何对双端队列进行高效排序呢?
最好的方法是先将双端队列中的元素放入vector中,再进行排序,可以使用快排,其效率较高。

4.string与vector的区别

string是STL中的一个容器,末尾必须有’\0’,有独立的算法,操作起来较方便。而vector是字符数组。

关联式容器可以点击:
https://blog.csdn.net/zwe7616175/article/details/80090353

map/set与unordered_map/unordered_set的区别?

1.底层实现不同,map/set底层是用红黑树实现的,而unordered_map/unordered_set底层是用哈希表实现的。
2.查找效率不同,map/set的查找时间复杂度为O(log2N),unordered_map/unordered_set查找的时间复杂度为O(N)。
3.遍历后,map/set是有序的,unordered_map/unordered_set是无序的。
4.哈希表存在冲突。
5.空间利用率不同,map/set是有多少给多少,unordered_map/unordered_set会给出多余的空间。

适配器

适配器有三种,改变容器接口的空间适配器、改变迭代器接口的迭代器适配器、改变仿函数接口的仿函数适配器。

STL提供了三种容器适配器:stack,queue,priority_queue。
栈、队列的底层是deque,优先级队列的底层是priority_queue。
适配器的优点是:能够使程序员选择一种合适的底层数据结构。

下面介绍几个空间适配器。

1、 stack适配器

stack类允许在底层数据结构的一端执行插入和删除操作(先入后出)。堆栈能够用任何序列容器实现:vector、list、deque。

堆栈的操作包括:
1.将一个元素插入到堆栈顶部的push函数(调用底层容器的push_back函数实现)
2.从堆栈的顶部删除一个元素的pop函数(调用底层元素的pop_back函数实现)
3.获取堆栈顶部元素引用的top函数(调用底层容器的back函数实现)
4.判断堆栈是否为空的empty函数(调用底层容器的empty函数实现)
5.获取堆栈元素数量的size函数(调用底层容器的size函数实现)
为了获得最佳性能,应使用vector类作为stack的底层容器

2、 queue适配器

queue类允许在底层数据结构的末尾插入元素,也允许从前面插入元素(先入先出)。

队列能够用STL数据结构的list和deque实现,默认情况下是用deque实现的。
常见的queue操作:
1.在队列末尾插入元素的push函数(调用底层容器的push_back函数实现)
2.在队列前面删除元素的pop函数(调用底层容器的pop_back函数实现)
3.获取队列中第一个元素的引用的front函数(调用底层容器的front函数实现)
4.获取队列最后一个元素的引用的back(调用底层容器的back函数实现)
5.判断队列是否为空的empty函数(调用底层容器的empty函数实现)
6.获取队列元素数量的size函数(调用底层容器的size函数实现)
为了获得最佳性能,应使用deque类作为queue的底层容器

3、 priority_queue适配器

priority_queue类,能够按照有序的方式在底层数据结构中执行插入操作,也能从底层数据结构的前面执行删除操作。

priority_queue能够用STL的序列容器vector和deque实现。默认情况下使用vector作为底层容器的。当元素添加到priority_queue时,它们按优先级顺序插入。

这样,具有最高优先级的元素,就是从priority_queue中首先被删除的元素。通常这是利用堆排序来实现的。

堆排序总是将最大值(即优先级最高的元素)放在数据结构的前面。这种数据结构称为(heap)

默认情况下,元素的比较是通过比较器函数对象less执行的。

priority_queue具有几个常见的操作:
1.根据priority_queue的优先级顺序在适当位置插入push函数(通过调用底层容器的push_back,然后使用堆排序为元素重新排序)
2.删除priority_queue的最高优先级元素的pop(删除堆顶元素之后通过调用底层容器的pop_back实现)
3.获取priority_queue的顶部元素引用的top函数(调用底层容器的front函数实现)
4.判断priority_queue是否为空的empty函数(调用底层容器的empty函数实现)
5.获取priority_queue元素数量的size函数(调用底层容器的size函数实现)
为了获取最佳性能,使用vector作为priority_queue的底层容器。

空间配置器

负责空间配置、管理、释放。内存池实现小块内存分配。

迭代器

提供一种方法,使之能够依序访问容器的各个元素,而不需要暴露出容器的内部。扮演容器与算法之间的粘合剂,共有五种类型,以及它的其他衍生变化,从实现角度来看,迭代器是一种将:Operator*、Operator->、Operator++、Operator–、Operator==。

仿函数

C++新标准采用的新名称为函数对象,实质是一个“行为类似函数的对象”,改写了函数调用的运算子operator()。举个例子,在使用sort时,我们想按照特定的规则进行排序,它允许我们传入一个仿函数,仿函数指定排序策略,使得算法更灵活。
为什么不用函数指针?函数指针不满足STL堆抽象性的要求;函数指针无法和STL的其他组件搭配,产生灵活的变化。

你可能感兴趣的:(STL)