一、什么是STL?
1,含义:STL是标准模板库,通俗来讲是常见的数据结构的封装和通用算法的结合(任意类型,不与数据结构相关)
2.特点:通用 容器--->模板
算法:模板+与数据结构无关
通用的算法:与数据类型无关--->模板
与数据结构无关--->迭代器
灵活,高效。
二、STL的六大组件
.容器是用来放东西的,而STL中的容器则是用来放数据的,因此也称数据容器。
三、序列式容器之Vector
vector底层是一段连续空间,因此vector的迭代器设计为一个原生态指针,即:所存储元素类型的指针。
使用vector的头文件:<vector> ,标准命名空间std;
四、序列容器之list
list底层是带头节点的双向循环链表。
迭代器的实现:
迭代器的本质是指针,是将指针封装出来的一种新的类型,因此指针有的操作,迭代器也要视情况支持这些操作。比如:
指针可以++、--、*、->、!=、==这些操作,迭代器在其中只需将这些操作符重载即可,最后只需将list迭代器类型与list
容器绑定在一起即可(将迭代器作为list的一种内部数据类型使用)。当利用迭代器来遍历list时,在迭代器上进行++操作,
它内部根据自己底层的结构就知道如何朝后去移动。
五、双端队列deque(动态二维数组,类似一段连续空间)
双向开口:指可以在两端分别进行元素的插入和删除操作,因此deque要求在常熟时间内对头进行数据的插入和删除操作。
操作原理图:
stack:用deque实现代价小,用vector实现,有增容机制->代价大
queue:用deque实现,小段连续,空间利用率高。
stack 和queue的底层都是deque来实现的。底层是deque接口的重新封装,形成的新的数据结构。
stack为什么没有迭代器?
因为栈只操作栈顶元素,不便利所有元素。
priority_queue (默认情况下是大堆)
底层是 vector+堆算法
需要小堆:priority_queue<int,vector<int>,greater<int>>
与vector相比,deque功能上的不同之处在于:
1)两端都能快速插入元素和删除元素(vector只在尾端快速进行此类操作)。
2)存取元素时,deque的内部结构会多一个间接过程,所以元素的存取和迭代器的动作会稍稍慢一些。
3)迭代器需要在不同区块间跳转,所以必须是特殊的智能型指针,非一般指针。
4)在对内存区块有所限制的系统中(例如PC系统),deque可以内含更多元素,因为它使用不止一块内存。因此deque的max_size()可能更大。
5)deque不支持对容量和内存重分配时机的控制。特别要注意的是,除了头尾两端,在任何地方插入或删除元素,都将导致指向deque元素的任何指针、引用、迭代器失效。不过,deque的内存重分配优于vector,因为其内部结构显示,deque不必在内存重分配时复制所有元素。
6)deque的内存区块不再被使用时,会被释放。deque的内存大小是可缩减的。
以下情形,最好采用deque:
1)需要在两端插入和删除元素。
2)无需引用容器内的元素。
3)要求容器释放不再使用的元素。
deque的各项操作只在以下几点和vector不同:
1)deque不提供容量操作(capacity()和reserve())。
2)deque直接提供函数,用以完成头部元素的插入和删除(push_front()和pop_front())。
六、关联式容器(键值对:key,value)
1.二叉搜索树
(1)最左侧一定是最小的结点,最右侧一定是最大的结点。
(2)中序遍历可以得到一个有序的序列。
(3)缺陷:如果插入的数据有序或接近有序,则退化成单支树,时间复杂度O(N).
2.AVL树
(1)平衡因子:左右子树的高度差
(2)双亲的平衡因子的绝对值>1,需要对以parent为根的树进行旋转处理。
(3)缺陷:删除操作复杂,性能差。
3.红黑树
(1)红黑树是一棵二叉搜索树,最长路径不超过最短路径的两倍。
(2)红黑树的性质
- 每个结点不是红色就是黑色
- 根结点是黑色的
- 没有连在一起的红色结点
- 每条路径中黑色节点的数目是一样的
- 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
(3)插入过程 (结点默认为红色)
按照二叉搜索树的规则插入新结点
如果新结点的双亲结点颜色如果是红色的,违反了性质3(没有连在一起的红色结点),需要对红黑树进行相应的处理。
注意:虽然红黑树是一棵近似平衡的搜索树,但是在实际应用中表现出的性能确实比AVL树更优,因此关联式容器选择红黑树作为其底层结构。
4.基于红黑树的关联式容器之map与multimap,set与multiset
5.基于哈希桶结构的unordered系列关联式容器
七、迭代器失效
1.迭代器的本质:指针
2.迭代器失效:指针指向的空间已经失效,不能访问。
3.vector的迭代器类型:原生态指针
list迭代器类型:将原生态指针封装
4.vector迭代器失效情况:有扩容操作(Insert,reserve,pushback),原来的空间已经失效。
解决方案:重新赋值
list迭代器失效:有删除操作(插入操作不会失效)