C++:map和unordered_map

最近面试被问到的一个问题,面试当然是挂了,但是收获还是需要分享一下的。

map

  • 底层实现是借助红黑树实现的
  • map插入一个节点的时间复杂度是O(log n)
  • 同样修改一个节点的时间复杂度是O(log n)

关于插入节点的时间复杂度,理解起来很简单,因为变色的时间复杂度是O(1)的,所以插入或者修改只需要找到节点即可,变色时间复杂度是O(1)是因为变色过程与节点数n无关而与节点状态有关。

unordered_map

  • 底层实现是哈希表
  • unordered_map插入一个节点的时间复杂度是O(1)
  • unordered_map修改一个节点的时间复杂度是O(1)

哈希表的结构在STL中有优化,如下图(绘图技术有限),绿色的是指针数组,黄色的是一个链表,绿色的长度应该是一个质数,绿色节点有数据要插入时先判断是否为空不为空就直接头插,为空的话指向虚头然后头插,这样的一种结构使得使用迭代器遍历时更加的高效,同时还减少了虚头节点的使用。

对哈希表来说他会维持一个哈希因子,计算方式很简单:存储节点数/指针数组的长度

当哈希因子到达一个阈值则认为哈希表"满了",然后进行扩容再哈希,这个阈值一般在0.5-1,这保证了哈希表的查询或者插入的时间复杂度可以达到O(1)(当然不考虑极端情况,你n个不同数据的哈希结果映射到了同一个坑里),这些当然都是基础,答上来很简单,注意以下内容。

map和unordered_map的使用情景

map对于每一时刻严格有序的,但是注意它适合小数据量并且节点数据修改不频繁的情况,对于大数据量来说对map可能单层节点需要多个文件页进行存储,你寻找节点时每一次需要产生大量的文件IO,它整体性能甚至低于B树(同等节点红黑树更深),所以对大规模数据时刻要求有序的情况使用B+树更加合适。

节点如果频繁进行修改的情况也是不适合的,因为查找的时间复杂度虽然只有O(log n)但是较于哈希表的O(1)还是太高了,所以一旦数据频繁修改记得用哈希表

那么如果要求有序且可能会进行频繁修改呢?

比如现在有一个排行榜,你会选择哪种数据结构呢?首先对排行榜修改的频率太高了,无论是红黑树还是B+树其实都是不合适的,所以应该使用哈希表存储然后定时刷新,即每过一段时间进行一次外部排序,这样虽然看起来时间复杂度更高了但是实际上更加合理,因为不能只考虑排序而忽略更新的过程。

map底层迭代器

红黑树作为一种有序的树形结构,它的迭代器是通过中序遍历完成创建的,迭代器作为对内存的一种抽象,它存储节点地址和节点信息,在map中维护成了一个链表结构用于进行树的遍历,同时对++/--这些运算符进行重载,重载内部完成迭代器对象间的跳转(pre指向上一个迭代器对象,next指向的是下一个迭代器对象,节点存储的地址是数据的地址)

STL刚开始学,有错误请指出。

相关推荐
自动驾驶小卡3 小时前
boost::circular_buffer的使用方法简介
c++·boost·circular_buffer
睡不醒的kun5 小时前
leetcode算法刷题的第三十二天
数据结构·c++·算法·leetcode·职场和发展·贪心算法·动态规划
乔宕一7 小时前
stm32 链接脚本没有 .gcc_except_table 段也能支持 C++ 异常
c++·stm32·嵌入式硬件
SuperCandyXu7 小时前
P3205 [HNOI2010] 合唱队-普及+/提高
c++·算法·洛谷
_君落羽_7 小时前
ARM寄存器以及异常处理
c++
free8 小时前
基于librdkafa C++客户端生产者发送数据失败问题处理#2
c++·kafka
小柯J桑_8 小时前
Linux:线程封装
linux·运维·c++
doll ~CJ9 小时前
基于QVTKOpenGLNativeWidget的三维点云可视化实现
c++·qt·软件开发·三维点云可视化
42fourtytoo10 小时前
天津大学智算2026预推免机试第二批题目及代码c++
开发语言·c++·面试
子豪-中国机器人11 小时前
枚举算法和排序算法能力测试
开发语言·c++·算法