Tips----1

STL

(1)序列式容器(Sequence containers),每个元素都有固定位置--取决于插入时机和地点,和元素值无关,vector、deque、list;
       Vector:将元素置于一个动态数组中加以管理,可以随机存取元素(用索引直接存取),数组尾部添加或移除元素非常快速。但是在中部或头部安插元素比较费时;
       Deque:是“double-ended queue”的缩写,可以随机存取元素(用索引直接存取),数组头部和尾部添加或移除元素都非常快速。但是在中部或头部安插元素比较费时;
       List:双向链表,不提供随机存取(按顺序走到需存取的元素,O(n)),在任何位置上执行插入或删除动作都非常迅速,内部只需调整一下指针;
(2)关联式容器(Associated containers),元素位置取决于特定的排序准则,和插入顺序无关,set、multiset、map、multimap等。
       Set/Multiset:内部的元素依据其值自动排序,Set内的相同数值的元素只能出现一次,Multisets内可包含多个数值相同的元素,内部由二叉树实现,便于查找;
       Map/Multimap:Map的元素是成对的键值/实值,内部的元素依据其值自动排序,Map内的相同数值的元素只能出现一次,Multimaps内可包含多个数值相同的元素,内部由二叉树实现,便于查找;

(3)容器适配器

      stack

      queue

      priority_queue

调用pop_back(),会将内存还给堆吗

一级空间配置器:用malloc()、free()、realloc()等C函数执行内存配置、释放、重配置操作,并实现出类似的C++new_hanle的机制。

SGI二级空间配置器的原理是:当区块小于128字节,则以内存池(memory pool)管理,回收时管理一个用户归还的空间,类似于哈希桶。

空间配置器也存在一些缺点,但总的来说是优点大于缺点的。
(1)内存并没有还给系统,只换给了空间配置器。有可能在申请大的内存块就不够了。
(2)外部碎片的问题解决了,又引入了内部碎片,自由链表下挂的小结点过多导致。
(3)只有在程序真正退出的时候,内存才释放。

一级/二级配置器

空间配置器,就是用来配置、管理和释放空间的,给所有的容器包括算法提供生存空间。

作用:

(1)提高代码复用率,功能模块化。
(2)减少内存碎片问题。
(3)提高内存分配的效率。
(4)有内存不足时的应对措施。
(5)隐藏实际中对存储空间的分配及释放细节,确保所有被分配的存储空间都最终获得释放。
(5)考虑多线程状态。

考虑到小型区块可能导致的内存碎片问题,设置了两级空间配置器。分别为:一级空间配置器、二级空间配置器。当区块大于128字节,调用一级空间配置器;小于等于128字节,为了降低额外开销,用底层较复杂的二级空间配置器。

map与hash_map区别

C++中,map(来自于 STL) ,底层实现采用红黑树。

hash_map(有很多种实现,底层实现均采用hashtable。目前普遍使用的来自 SGI 的 STL),还未成为C++标准,不过,在可预见的将来,会成为C++标准。

unordered_map 实现来自于 boost 库,底层实现也是hashtable。


unordered_map的初始化比较耗时,我们都知道map是红黑树,unordered_map是哈希表,造成性能差异的原因在于,红黑树初始化时,节点只需要一个,后续的插入只是插入新的节点,但是哈希表初始化时就不是那么简单了,哈希表初始化时需要申请一个数组,数组的每个元素都指向一条链表,所以初始化时需要申请很多内存,相比于map,的确更耗时。

相对于平衡树,hashtable的优点:

插入,查找,删除复杂度为常数时间,大规模查询时,性能差距更为明显。

其实相比于hash,平衡树也是有优点的:

1. 尽管我们都说hash查找插入删除复杂度是常数时间,但这仅仅是个统计上的概念,最差情况下,也是会达到O(n),而红黑树,最差的情况下也是O(logn)

2.hash实际上是空间换时间的做法,空间越小,操作的时间复杂度越大,操作时间越不稳定,而平衡树则稳定很多

3.还有一个就是序,红黑树是查找树,因此中序遍历的结果就是排好序的。这就使得其在范围查找方面性能优秀,而hash却需要遍历全部数据,之后统计才能得出范围查找的结果。另外,如果你知道一个元素在树中的位置,和它大小相近的元素也在它周围,这就使得获取相近元素的时间很少。另外,我们知道,中序遍历的时间复杂度也只是O(n),这个性质非常有用。

至于unordered_map,原理和hash_map类似,但其在某些方面做了优化,性能好于hash_map,所以,业界有一个建议,如果不是为了有序,尽量使用unordered_map。

RB与AVL区别

1. 如果插入一个node引起了树的不平衡,AVL和RB-Tree都是最多只需要2次旋转操作,即两者都是O(1);但是在删除node引起树的不平衡时,最坏情况下,AVL需要维护从被删node到root这条路径上所有node的平衡性,因此需要旋转的量级O(logN),而RB-Tree最多只需3次旋转,只需要O(1)的复杂度。

2. 其次,AVL的结构相较RB-Tree来说更为平衡,在插入和删除node更容易引起Tree的unbalance,因此在大量数据需要插入或者删除时,AVL需要rebalance的频率会更高。因此,RB-Tree在需要大量插入和删除node的场景下,效率更高。自然,由于AVL高度平衡,因此AVL的search效率更高。

3. map的实现只是折衷了两者在search、insert以及delete下的效率。总体来说,RB-tree的统计性能是高于AVL的。

multimap插入重复数据会如何存放

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值