1.STL知识梳理
STL知识掌握:
底层实现角度:六大组件
上层用的角度:容器、算法、迭代器
底层实现角度:
注:
1.可以认为迭代器是容器和算法的粘合剂,如果没有迭代器,那么算法要访问容器有两大问题:
(1)访问需要暴露容器底层结构及实现细节,封装性就不在了。
(2)使用门槛较高,比如要访问map,需要对二叉树遍历掌握,这个成本是很高的。
通过迭代器解决了上面的问题,迭代器优势如下:
(1)封装隐藏了底层实现细节。
(2)提供统一的方式去访问容器,极大降低了使用成本。
2.容器如果频繁的申请小块内存,就需要空间配置器来提高内存申请和释放的效率。
3.容器适配器:stack、queue、priority_queue等。适配器可以认为是一种特殊的容器,体现了复用的思想。
其他适配器:反向迭代器也是一种适配器,封装容器正向迭代器就可以实现这个容器的反向迭代器。
4.仿函数主要作用在容器和算法上,其本质上是实现了operator()的类,这个类对象可以像函数一样去使用。使用场景举例:
场景一:map/set的key比较大小规则。
场景二:unoredered_map/unoredered_set的key转换成整型的规则,影响冲突率。
场景三:sort排序比较规则。
上层用的角度:
注:
1.重点熟练掌握的容器:vector、list、map、set、unoredered_map、unoredered_set。
map和set:
(1)需要熟练掌握这些容器的常见接口使用(增删查改:insert、erase、find、operator[]、iterator)
(2)常见经典问题,例如:
底层实现原理,即红黑树。掌握红黑树的规则、增删查改的效率。
operator[ ]的返回值是什么?答:value的引用。
一个类型要做map和set的K有什么要求?答:要支持比较大小,因为底层是搜索树。
map和set有什么特点?答:查找效率,遍历时按key排序的,可以对key去重。
(3)multi版本特点。
unoredered_map和unoredered_set:
(1)需要熟练掌握这些容器的常见接口使用(增删查改:insert、erase、find、operator[]、iterator)
(2)常见经典问题,例如:
底层实现原理,即哈希表。
一个类型要做unoredered_map和unoredered_set的K有什么要求?答:能取模或者配一个哈希的仿函数支持转成整型取模,支持==比较。
unoredered_map和unoredered_set相比map和set的特点是什么?答:查找平均是O(1)(更快),遍历是无序的。
(3)multi版本特点。
vector和list:
(1)需要熟练掌握这些容器的常见接口使用(增删查改+iterator)
(2)常见经典问题,例如:
vector和list的区别?答:vector优点是适合尾插尾删和下标的随机访问,vector缺点是头部中间插入删除需要挪动数据效率低,并且扩容也有代价。list优点是任意位置O(1)的插入删除,并且可以按需申请释放,list缺点是不支持随机访问。
vector如何扩容?答:一般是2倍扩容,但不一定非得是2倍,只是2倍左右合适。一次扩容扩多了浪费,扩少了会频繁扩容效率降低。