STL容器复习

23、常见容器性质总结?

  1. vector 底层数据结构为数组 ,支持随机访问
  2. list 底层数据结构为双向链表,支持快速增删
  3. deque 底层数据结构为一个中央控制器和多个缓冲区,支持首尾(中间不能)快速增删,支持随机访问。deque是一个双端队列(double-ended queue),也是在堆中保存内容的.它的保存形式如下:[堆1] --> [堆2] -->[堆3] --> …每个堆保存好几个元素,然后堆和堆之间有指针指向,看起来像是list和vector的结合品.
  4. stack 底层一般用list或deque实现,封闭头部即可,不用vector的原因应该是容量大小有限制,扩容耗时(vector整篇迁移,而deque的扩容是实打实的连接一片连续空间过来)
  5. queue 底层一般用list或deque实现,封闭头部即可,不用vector的原因应该是容量大小有限制,扩容耗时(stack和queue其实是适配器,而不叫容器,因为是对容器的再封装)
  6. priority_queue 的底层数据结构一般为vector为底层容器,堆heap为处理规则来管理底层容器实现
  7. set 底层数据结构为红黑树,有序,不重复
  8. multiset 底层数据结构为红黑树,有序,可重复
  9. map 底层数据结构为红黑树,有序,不重复
  10. multimap 底层数据结构为红黑树,有序,可重复
  11. unordered_set 底层数据结构为hash表,无序,不重复
  12. unordered_multiset 底层数据结构为hash表,无序,可重复
  13. unordered_map 底层数据结构为hash表,无序,不重复
  14. unordered_multimap 底层数据结构为hash表,无序,可重复

27、STL中vector的实现

  1. arry是在栈或者全局数据区上,静态分配内存,配置后不可改变大小,灵活性差但效率高。
  2. vector在堆上,速度没arry快但灵活性好,动态配置空间,维护一块连续的空间,可以自动扩展容纳新元素。随机访问迭代器。扩容规则:以原大小的两倍配置另外一块较大的空间,在Linux+Gcc下是2倍,在win+vs下是1.5倍。频繁对vector调用push_back()对性能是有影响的,这是因为每插入一个元素,如果空间够用的话还能直接插入,若空间不够用,则需要重新配置空间,移动数据,释放原空间等操作,对程序性能会造成一定的影响

28、STL中slist的实现

使用单向链表实现,相比list耗用空间更小。由于是单向链表,考虑效率问题只提供了push_front()操作(头插),所以存进去顺序跟输出顺序相反。提供insert_after()和erase_after()

29、STL中list的实现

双向链表,支持在头部(front)和尾部(back)两个方向进行push和pop操作


30、STL中的deque的实现

相比vector的单端开口,deque是双端开口,头尾的增删O(1),由分段空间连接组成,不像vector的连续空间,没有容量的概念,支持随机访问迭代器。deque内部有一个指向map的指针,map的每个元素都指向另一端更大的缓冲区,缓冲区才是真正存数据的地方。所以deque的迭代器++和–操作复杂,主要工作在缓冲区边界跳到另一个缓冲区时。因此除了必要一般使用vector,如果要对deque排序一般可以复制deque元素到vector中,sort后再把结果复制回去。
当map的node都用完了,并且所有node指向的缓冲区都用完了,map将重新配置来 2*当前+2的数量来容纳更多node,也就是指向更多缓冲区。 中控器就是map
image.png

31、STL中stack和queue的实现(两者没有迭代器)

**stack:**容器配接器,不提供迭代器。stack底层是deque容器,移除了一端接口就行了,也开始使用双向开口的list实现。(源码上参数2用list就行了)
image.png

**queue:**底层也是 deque,也可以用list作为底层容器,容器配接器,没有遍历功能,没有迭代器。

32、STL中的heap的实现

  1. heap(堆)并不是STL的容器组件,堆排序是priority queue(优先队列)的底层实现机制。大根堆其实可以用vector跟一组heap算法实现。
  2. heap算法有push_heap(加入大根堆)和pop_heap(下溯,其实是放到vector末尾)
  3. sort(因为pop的时候会把最大值放到vector末尾,所以不断的调用,最后vector会变成一个递增序列)
  4. make_heap(),以vector为底层容器把一段数据转换为heap,也就是不断调用push_heap实现


33、STL中的priority_queue的实现–容器配接器

跟队列一样一端进一端出,但是进元素时是根据元素值排列进的。用vector作为底层容器,heap作为管理规则(堆排)。每次只能拿到优先队列中权值最大的那个

34、STL中set的实现?

  1. 迭代器是常量迭代器,不允许通过迭代器修改元素值(会破坏有序性和唯一性),set元素自动排升序,不允许重复。要修改元素值的话—>删除,再加入元素
  2. 底层是红黑树实现的,红黑树特点:二叉排序树、查询和维护复杂度是O(logn),根节点是黑,如果节点是红,子节点必黑,某节点到NULL的每条路径上,黑色节点数目相等。
  3. 关联式容器(set、map、multiset、multimap)使用自身提供的find()更快,因为通用标准库的find按顺序查找,复杂度是O(n),而关联式容器是树结构,自身的find()使用二分查找时间复杂度是O(logn)
  4. 无序关联式容器指的是用哈希表实现的unordder set \unordermap,查询速度是O(1)。

35、STL中map的实现

  1. 标准map底层是红黑树,另外有一种底层机制是哈希表的称为hash_map。
  2. 即带order的有序的都是红黑树实现的,优点是有序,不带order的哈希表实现,优点是查询效率高。unorder是哈希表实现的:unorder set, unorder map。

36、set和map的区别,multimap和multiset的区别

  1. set放值。map放键值对。
  2. multi跟非multi的差别就在于调用红黑树的插入的方式不同:普通的set(非multi)使用红色树的insert_unique()独一无二插入,mult使用insert_equal()可重复插入。

37、STL中unordered_map和map的区别和应用场景

map适用于有序场景,unordermap适用于高效查询场景

38、哈希表中解决冲突方法?

  1. 线性探测:根据hash函数计算找到第一个不冲突的,如果被占用就回到表头,直到找到一个空位
  2. 开链:每个表格维护一个list,hash函数计算结果与格子相同则存到这个list
  3. 再散列:发送冲突使用另一个hash函数再计算一个地址

学习资源来自师兄拓扑阿秀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值