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刚开始学,有错误请指出。

相关推荐
2601_9561219711 小时前
二分算法(知识点+题目)
c++·算法
蒙奇·D·路飞-13 小时前
OpenClaw:开源的《合金弹头》精神续作与终极本地部署指南
c++·开源·mfc
小星星闪亮登场15 小时前
2026萌新联赛第三场-- (郑州轻工业大学)
数据结构·c++·经验分享·算法·贪心算法·排序算法·深度优先
梓䈑15 小时前
【用 Vibe Coding 实现的 C++17 在线判题系统】前端开发 + Web 自动化测试
前端·c++·ai编程
冻柠檬飞冰走茶15 小时前
PTA基础编程题目集 7-8超速判断(C++语言实现)
开发语言·数据结构·c++·算法
TunerT_TQ16 小时前
Valhalla 静态工程审阅 #018|MMCV 源码证据驱动评测【大厂开源基础设施特辑】
c++·开源·mfc·#计算机视觉·#商汤科技·#openmmlab·#静态源码审计
别动我齐刘海17 小时前
Day6 unitree_G1人形机器人GMR—— MotionInput
c语言·c++·人工智能·学习·机器学习·机器人·github
Henry Zhu12318 小时前
C++17 `weak_from_this` 详解:让对象安全地观察自己
c++
June`21 小时前
warp shuffle指令
c++·人工智能·算法·cuda
乱七八糟的屋子21 小时前
【C++数值计算】NumCpp超详细入门教程(纯正Numpy语法、零学习成本、C++首选科学计算库、性能压测对比)
c++·数值计算·numpy·高性能计算·科学计算·ndarray