全面总结:常见数据结构时间复杂度比较表
创作时间:
作者:
@小白创作中心
全面总结:常见数据结构时间复杂度比较表
引用
CSDN
1.
https://blog.csdn.net/weidl001/article/details/144222476
本文总结了常见数据结构的时间复杂度,并附带了一些关于图的存储方式的额外知识点。内容结构清晰,包含了单链表、双链表、循环链表、栈、队列、数组、哈希表、二叉搜索树和堆等数据结构的常见操作及其时间复杂度。此外,还提供了关于如何选择数据结构的建议,以及图的存储方式(邻接矩阵和邻接表)的对比分析。
常见数据结构时间复杂度比较表
数据结构 | 操作 | 平均时间复杂度 | 最坏时间复杂度 | 说明 |
|---|---|---|---|---|
单链表 | 查找(搜索) | O(n) | O(n) | 需要从头遍历到目标位置。 |
插入头部 | O(1) | O(1) | 常数时间插入新节点,修改头指针。 | |
插入尾部 | O(n) | O(n) | 需要遍历到尾节点,除非有尾指针。 | |
插入任意位置 | O(n) | O(n) | 需要遍历到指定位置。 | |
删除头部 | O(1) | O(1) | 修改头指针即可。 | |
删除尾部 | O(n) | O(n) | 需要找到尾节点的前驱节点。 | |
删除任意节点 | O(n) | O(n) | 需要找到目标节点的位置。 | |
遍历 | O(n) | O(n) | 遍历整个链表的所有节点。 | |
双链表 | 查找(搜索) | O(n) | O(n) | 与单链表相同。 |
插入头部 | O(1) | O(1) | 常数时间修改头指针和新节点的prev指针。 | |
插入尾部 | O(1) | O(1) | 通过尾指针直接访问,常数时间完成。 | |
插入任意位置 | O(n) | O(n) | 需要遍历到指定位置。 | |
删除头部 | O(1) | O(1) | 修改头指针和新头节点的prev指针即可。 | |
删除尾部 | O(1) | O(1) | 修改尾指针和前驱节点的next指针。 | |
删除任意节点 | O(n) | O(n) | 需要找到目标节点。 | |
遍历 | O(n) | O(n) | 遍历整个链表的所有节点。 | |
循环链表 | 查找(搜索) | O(n) | O(n) | 与单链表相同。 |
插入头部 | O(n) | O(n) | 需要找到尾节点以更新其next指针。 | |
插入尾部 | O(n) | O(n) | 需要遍历到尾节点,除非维护尾指针。 | |
删除头部 | O(n) | O(n) | 需要找到尾节点以更新其next指针。 | |
删除尾部 | O(n) | O(n) | 需要找到尾节点和其前驱节点。 | |
遍历 | O(n) | O(n) | 遍历整个循环链表,直到回到头节点。 | |
栈(链表实现) | 入栈(Push) | O(1) | O(1) | 常数时间在头部插入节点。 |
出栈(Pop) | O(1) | O(1) | 常数时间删除头部节点。 | |
获取栈顶(Peek) | O(1) | O(1) | 常数时间访问头部节点。 | |
判断是否为空 | O(1) | O(1) | 判断头指针是否为NULL。 | |
队列(链表实现) | 入队(Enqueue) | O(1) | O(1) | 常数时间在尾部插入节点。 |
出队(Dequeue) | O(1) | O(1) | 常数时间删除头部节点。 | |
获取队头(Front) | O(1) | O(1) | 常数时间访问头部节点。 | |
判断是否为空 | O(1) | O(1) | 判断头指针是否为NULL。 | |
数组 | 查找(按索引) | O(1) | O(1) | 常数时间直接访问目标索引。 |
插入(随机位置) | O(n) | O(n) | 插入位置后的所有元素需要移动。 | |
删除(随机位置) | O(n) | O(n) | 删除位置后的所有元素需要移动。 | |
遍历 | O(n) | O(n) | 遍历整个数组。 | |
哈希表 | 查找 | O(1) | O(n) | 平均情况O(1),最坏情况哈希冲突导致线性查找。 |
插入 | O(1) | O(n) | 平均情况O(1),最坏情况哈希冲突导致线性查找。 | |
删除 | O(1) | O(n) | 平均情况O(1),最坏情况哈希冲突导致线性查找。 | |
二叉搜索树 | 查找 | O(log n) | O(n) | 平衡树的平均时间复杂度为O(log n),退化为链表时最坏O(n)。 |
插入 | O(log n) | O(n) | 平衡树的平均时间复杂度为O(log n),退化为链表时最坏O(n)。 | |
删除 | O(log n) | O(n) | 平衡树的平均时间复杂度为O(log n),退化为链表时最坏O(n)。 | |
遍历 | O(n) | O(n) | 访问所有节点的总时间。 | |
堆(优先队列) | 插入 | O(log n) | O(log n) | 维护堆的结构需要对数时间。 |
删除最大/最小值 | O(log n) | O(log n) | 删除根节点并调整堆结构需要对数时间。 | |
获取最大/最小值 | O(1) | O(1) | 直接访问根节点。 |
说明与使用指南
- 如何选择数据结构:
- 链表:适用于需要动态插入、删除的场景,但查找速度较慢。
- 数组:适用于需要快速访问(随机访问)的场景,但插入和删除效率低。
- 栈与队列:专注于特定操作(LIFO/FIFO),高效且易于实现。
- 哈希表:适用于需要快速查找和插入的场景,但可能需要处理冲突。
- 二叉搜索树:适用于需要排序的动态集合,但需要注意树的平衡性。
- 堆:适用于需要高效获取最大值或最小值的优先级队列场景。
- 时间复杂度决定了效率:
- 对于大规模数据,优先选择具有对数时间复杂度或更优性能的数据结构。
- 在特定情况下(如数据较小或操作较少),简单的实现可能更具优势。
- 结合操作特点优化:
- 例如,在频繁插入尾部的链表中,可以通过维护尾指针将时间复杂度从O(n)优化为O(1)。
这张表格可以作为快速查阅和理解常见数据结构的参考。对于每种数据结构的实现和应用,推荐结合具体问题场景深入实践和优化。
图的存储方式
题目
- 设有一稠密图 G,问 G 采用何种存储方式较省空间?
正确答案:邻接矩阵
解析
- 图的稠密性定义
- 一个图的稠密程度取决于边的数量。假设图 G 有 n 个顶点:
- 如果图中实际边数接近于最多可能的边数 n×(n−1)/2(无向图)或 n×(n−1)(有向图),则称为稠密图。
- 反之,如果图的边数远小于上述值,则称为稀疏图。
- 两种常见图的存储结构
- 邻接矩阵(Adjacency Matrix)
- 使用一个 n×n 的二维数组存储图的信息。
- 如果顶点 i 和顶点 j 有边,则 matrix[i][j]=1(或权重值);否则为 0。
- 空间复杂度固定为 O(n2)。
- 邻接表(Adjacency List)
- 每个顶点维护一个链表,链表中存储与该顶点相连的所有边。
- 空间复杂度为 O(n+e),其中 e 是边的数量。
- 稠密图为何选择邻接矩阵?
- 对于稠密图,边的数量 e 接近 n2,邻接表的空间复杂度接近 O(n+n2),且复杂的链表结构本身会增加存储开销。
- 相比之下,邻接矩阵的固定空间复杂度 O(n2) 更适合存储稠密图,因为不需要额外维护链表结构。
- 稀疏图的对比
- 如果是稀疏图,边数 e 远小于 n2,邻接表的空间复杂度 O(n+e) 比邻接矩阵 O(n2) 更小,适合稀疏图。
知识点总结表格
存储方式 | 适用场景 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
邻接矩阵 | 稠密图 | O(n2) | 简单直观,适合快速查询两点是否相连 | 对稀疏图浪费大量空间 |
邻接表 | 稀疏图 | O(n+e) | 节省空间,特别是稀疏图 | 查询任意两点是否相连时效率较低 |
热门推荐
古玉沁色成因揭秘:从白沁到彩沁的科学解释
更年期的失眠,或是因为体内缺少它
冬游西藏正当时:6天行程玩转珠峰大本营和三大圣湖
肇庆七星岩:七座山峰如北斗,500幅石刻诉说千年文化
冬日大同:云冈石窟晨曦、悬空寺雪景、木塔千年传奇
米朵:从“看脸”到“走心”的情感觉醒
传统与现代交织,香港三大文化新地标亮相西九龙
美容缝合新选择:华佗隐形针实现无痕愈合
函数知识系统梳理:四大类型、解题技巧与应用
企业注销费用知多少?
公司注销全流程解析:省钱秘籍大公开
田曦薇出演的6部电视剧,每一部都是经典,你都看过哪部?
马斯克如何高效工作?揭秘他的时间管理与创新思维
王楚钦:从追光少年到世界冠军的蜕变
延安市人民医院专家解析:家中老人固执怎么办?
王楚钦福冈总决赛横扫张本智和,锁定年终世界第一
张钧甯的保养秘诀:运动瘦脸+食补养颜
11月到2月游泰国:20-30度宜人气候,这些节日和景点不容错过
中国心梗救治日:心肌梗死早期症状识别指南
诗意疗愈精神创伤
新疆骆驼奶与牛奶、羊奶有什么不同
基督教炽天使:六对翅膀背后的神圣象征
蔬菜种植:农家肥与化肥的合理搭配及全程施肥方案
生产环境运维必备:20个问题定位与解决指南
大疆无人机高压线飞行攻略,你get了吗?
越王勾践与兰亭:绍兴古城的文化密码
中国骨科医院设备升级,你家附近有吗?
南宋至清代三艘沉船出土,揭示海上丝路贸易变迁
中国新型隐形战斗机曝光,西方措手不及
想挑选一台可以除甲醛的空气净化器?一定要关注这些指标