c++面经(八)

heap
堆并不属于 STL 容器组件,它是个幕后英雄,扮演 priority_queue 的助⼿, priority_queue 允许⽤户以任何次序
将任何元素推⼊容器内,但取出时⼀定是从优先权最⾼(数值最⾼)的元素开始取。⼤根堆( binary max heap
正具有这样的性质,适合作为 priority_queue 的底层机制。
⼤根堆,是⼀个满⾜每个节点的键值都⼤于或等于其⼦节点键值的⼆叉树(具体实现是⼀个 vector ,⼀块连续空
间,通过维护某种顺序来实现这个⼆叉树),新加⼊元素时,新加⼊的元素要放在最下⼀层为叶节点,即具体实现
是填补在由左⾄右的第⼀个空格(即把新元素插⼊在底层 vector end() ),然后执⾏⼀个所谓上溯的程序:将新
节点拿来与 ⽗节点⽐较,如果其键值⽐⽗节点⼤,就⽗⼦对换位置,如此⼀直上溯,直到不需要对换或直到根节点
为⽌。当取出⼀个元素时,最⼤值在根节点,取⾛根节点,要割舍最下层最右边的右节点,并将其值᯿新安插⾄最
⼤堆,最末节点放⼊根节点后,进⾏⼀个下溯程序:将空间节点和其较⼤的节点对调,并持续下⽅,直到叶节点为
⽌。
priority_queue
底层时⼀个 vector ,使⽤ heap 形成的算法,插⼊,获取 heap 中元素的算法,维护这个 vector ,以达到允许⽤户
以任何次序将任何元素插⼊容器内,但取出时⼀定是从优先权最⾼(数值最⾼)的元素开始取的⽬的。
slist STL list 是⼀个双向链表, slist 是⼀个单向链表。
2 vector 使⽤的注意点及其原因,频繁对 vector 调⽤ push_back()
能影响
使⽤注意点:
注意插⼊和删除元素后迭代器失效的问题;
清空 vector 数据时,如果保存的数据项是指针类型,需要逐项 delete ,否则会造成内存泄漏。
频繁调⽤ push_back() 影响:
vector 的尾部添加元素,很有可能引起整个对象 存储空间的᯿新分配,᯿新分配更⼤的内存,再将原数据拷⻉
到新空间中,再释 放原有内存,这个过程是耗时耗⼒的,频繁对 vector 调⽤ push_back() 会导致性能的下降。
C++11 之后, vector 容器中添加了新的⽅法: emplace_back() ,和 push_back() ⼀样的是都是在容器
末尾添加⼀个新的元素进去,不同的是 emplace_back() 在效率上相⽐较于 push_back() 有了⼀定的提升。
emplace_back() 函数在原理上⽐ push_back() 有了⼀定的改进,包括在内存优化⽅⾯和运⾏效率⽅⾯。内存
优化主要体现在使⽤了 就地构造(直接在容器内构造对象,不⽤拷⻉⼀个复制品再使⽤) + 强制类型转换 的⽅法来
实现,在运⾏效率⽅⾯,由于省去了拷⻉构造过程,因此也有⼀定的提升。
3 map set 有什么区别,分别⼜是怎么实现的?
map set 都是 C++ 的关联容器,其底层实现都是红⿊树( RB-Tree )。
由于 map set 所开放的各种操作接⼝, RB-tree 也都提供了,所以⼏乎所有的 map set 的操作⾏为,都只是
转调 RB-tree 的操作⾏为。
map set 区别在于:
1 map 中的元素是 key-value (关键字 值)对:关键字起到索引的作⽤,值则表示与索引相关联的数据; Set
与之相对就是关键字的简单集合, set 中每个元素只包含⼀个关键字。
2 set 的迭代器是 const 的,不允许修改元素的值; map 允许修改 value ,但不允许修改 key 。其原因是因为
map set 是根据关键字排序来保证其有序性的,如果允许修改 key 的话,那么⾸先需要删除该键,然后调节平衡,
再插⼊修改后的键值,调节平衡,如此⼀来,严᯿破坏了 map set 的结构,导致 iterator 失效,不知道应该指向改
变前的位置,还是指向改变后的位置。所以 STL 中将 set 的迭代器设置成 const ,不允许修改迭代器的值;⽽ map
迭代器则不允许修改 key 值,允许修改 value 值。
3 map ⽀持下标操作, set 不⽀持下标操作。 map 可以⽤ key 做下标, map 的下标运算符 [ ] 将关键码作为下标去
执⾏查找,如果关键码不存在,则插⼊⼀个具有该关键码和 mapped_type 类型默认值的元素⾄ map 中,因此下标
运算符 [ ] map 应⽤中需要慎⽤, const_map 不能⽤,只希望确定某⼀个关键值是否存在⽽不希望插⼊元素时也不
应该使⽤, mapped_type 类型没有默认值也不应该使⽤。如果 find 能解决需要,尽可能⽤ find
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值