文章目录
1. 为何map和set的插入删除效率比其他序列容器高,为何map和set每次Insert之后,以前保存的iterator不会失效?
因为不需要内存拷贝和内存移动;
因为插入操作只是结点指针换来换去,结点内存没有改变。而iterator就像指向结点的指针,内存没变,指
向内存的指针也不会变。
2. 当数据元素增多时(从10000到20000),map的set的查找速度会怎样变化?
RB-TREE用二分查找法,时间复杂度为logn,所以从10000增到20000时,查找次数从log10000=14次到
log20000=15次,多了1次而已。
3. map 、set、multiset、multimap的特点
- set和multiset会根据特定的排序准则自动将元素排序,set中元素不允许重复,multiset可以重复。
- map和multimap将key和value组成的pair作为元素,根据key的排序准则自动将元素排序(因为红黑树也是二叉搜索树,所以map默认是按key排序的),map中元素的key不允许重复,multimap可以重复。
- map和set的增删改查速度为都是logn,是比较高效的。
4. 迭代器失效的问题
- 对于vector和string,如果容器内存被重新分配,iterators,pointers,references失效;如果没有重新分配,
那么插入点之前的iterator有效,插入点之后的iterator失效; - 对于deque,如果插入点位于除front和back的其它位置,iterators,pointers,references失效;当我们插入
元素到front和back时,deque的迭代器失效,但reference和pointers有效; - 对于list和forward_list,所有的iterator,pointer和refercnce有效。 删除操作:
- 对于vector和string,删除点之前的iterators,pointers,references有效;off-the-end迭代器总是失效的;
- 对于deque,如果删除点位于除front和back的其它位置,iterators,pointers,references失效;当我们插入
元素到front和back时,off-the-end失效,其他的iterators,pointers,references有效; - 对于list和forward_list,所有的iterator,pointer和refercnce有效。
- 对于关联容器map来说,如果某一个元素已经被删除,那么其对应的迭代器就失效了,不应该再被使用,否
则会导致程序无定义的行为。
5. set的底层实现实现为什么不用哈希表而使用红黑树?
- set中元素是经过排序的,红黑树也是有序的,哈希是无序的
- 如果只是单纯的查找元素的话,那么肯定要选哈希表了,因为哈希表在的最好查找时间复杂度为O(1),并且
如果用到set中那么查找时间复杂度的一直是O(1),因为set中是不允许有元素重复的。而红黑树的查找时
间复杂度为O(lgn)
6. hash_map与map的区别?什么时候用hash_map,什么时候用map?
- 构造函数:hash_map需要hash function和等于函数,而map需要比较函数(大于或小于)。
- 存储结构:hash_map以hashtable为底层,而map以RB-TREE为底层。
- 总的说来,hash_map查找速度比map快,而且查找速度基本和数据量大小无关,属于常数级别。而map的
查找速度是logn级别。但不一定常数就比log小,而且hash_map还有hash function耗时。 - 如果考虑效率,特别当元素达到一定数量级时,用hash_map。
- 考虑内存,或者元素数量较少时,用map。