【技能进阶4】关于算法,你需要掌握的数据结构图文手册

嵌入式看一半就够了~

大 O 表示法 — 时间复杂度

alt

为什么大 O 复杂度很重要?

对于小规模数据集,算法的复杂度可能不会显著影响性能,但随着数据规模的增加,算法的性能差异就变得至关重要。算法的复杂度直接影响到程序的响应时间和执行效率。因此,掌握时间复杂度对于编写高效程序是每个开发者必备的技能。

例如,假设数据集包含 100 万个元素:

  • O(1) 算法:执行 1 次操作。
  • O(log(n)) 算法:执行约 20 次操作。
  • O(n) 算法:执行 100 万次操作。
  • O(n * log(n)) 算法:执行约 2000 万次操作。
  • O(n²) 算法:执行 1 万亿次操作。

从这个简单的例子可以看出,算法复杂度在大规模数据处理中起着至关重要的作用。

RUM 权衡

选择合适的数据结构时,我们需要平衡三个方面的性能:

  • 读取效率 (R):从数据结构中检索或访问数据的速度。
  • 更新效率 (U):在数据结构中插入、删除或修改数据的速度。
  • 内存效率 (M):数据结构使用的内存空间。

这些因素之间通常存在一定的权衡,选择适合的结构是设计高效系统的关键。

alt

常见且重要的数据结构

数组与链表

  • 数组:数组在内存中连续存储,支持快速查找(O(1)),但插入和删除操作较慢(O(n))。
  • 链表:链表通过指针链接元素,支持快速插入和删除(O(1)),但查找操作较慢(O(n))。

alt

队列

队列是一种遵循“先进先出”(FIFO)原则的线性数据结构,适用于需要顺序处理任务的场景,如任务调度和消息队列。

alt

堆栈

堆栈遵循“后进先出”(LIFO)原则,适用于需要跟踪任务顺序的场景,比如函数调用栈或撤销操作。

alt

哈希表

哈希表提供常数时间(O(1))的元素访问,通过哈希函数将键映射到数组索引,实现高效的查找、插入和删除。其缺点是较高的内存消耗。

alt

树形数据结构

树形结构常用于组织层次化数据,广泛应用于数据库、文件系统和图形用户界面等领域。理解树结构的核心算法(如二分查找)对于掌握后续数据结构至关重要。

二分查找

二分查找是一种高效的排序数组查找算法。它通过每次将搜索空间缩小一半来寻找目标元素。时间复杂度为 O(log(n)),大大提高了查找效率。

alt

二叉搜索树(BST)

二叉搜索树是一棵二叉树,其中每个节点的左子树的值小于父节点,右子树的值大于父节点。平衡的二叉搜索树可以实现 O(log(n)) 的查找、插入和删除操作。

alt

红黑树

红黑树是一种自平衡的二叉搜索树,通过对每个节点赋予颜色(红色或黑色)并遵循一定的平衡规则,保证树的高度不会过高,从而维持高效的操作性能。

alt

AVL 树

AVL 树的全称是 Adelson-Velsky and Landis Tree,以其发明者 G. M. Adelson-Velsky 和 E. M. Landis 的名字命名。

AVL 树是一种自平衡的二叉搜索树,它通过限制左右子树的高度差不超过 1 来保持平衡。在插入和删除节点时,AVL 树会通过旋转操作进行自动平衡。

alt

堆是一种特殊的完全二叉树,分为最大堆和最小堆。最大堆中每个父节点的值大于或等于其子节点的值,最小堆则相反。堆常用于实现优先队列,能够高效地获取最小值或最大值。

alt

跳表

跳表是链表的一种扩展,通过多个层次的链表加速查找、插入和删除操作。其效率接近平衡树,但实现起来更为简单,适用于对效率要求较高的应用场景。

alt

B+ 树

B+ 树是一种广泛应用于数据库存储的平衡树结构,它将所有的数据存储在叶子节点,并通过有序的链表连接叶子节点,支持高效的顺序遍历。

alt

二叉索引树/斐波那契树

这种树结构主要用于处理动态频率表或区间查询,能够高效地支持前缀和查询。通过位移操作,更新和查询操作的时间复杂度为 O(log(n))。

alt

图数据结构

邻接表与邻接矩阵

  • 邻接表:将图的每个节点与其邻接节点通过列表存储,适用于稀疏图。

alt

  • 邻接矩阵:使用一个二维矩阵来表示节点之间的连接关系,适用于稠密图。

alt

字符串搜索数据结构

Trie(字典树)

Trie 是一种高效的字符串搜索数据结构,特别适用于前缀查询和单词自动补全等应用。每个节点代表一个字符,能够快速查找字符串的前缀(我觉得这张图好好看,像葡萄藤)。

alt

Radix Tree

Radix 树是一个紧凑的 Trie,通过合并公共前缀节点来减少空间消耗,适合用于处理大量字符串数据。

alt

Splay Tree

伸展树是一种自调整的二叉搜索树,每次访问节点后,它会自动将该节点移到树的根部,从而加快对频繁访问节点的查询效率。

alt

Quadtree

四叉树是一种空间数据结构,通常用于二维空间的区域分割,如碰撞检测或图形处理。每个节点将空间分割为四个子区域。

alt

KD Tree

KD 树是一种针对 k 维空间的二叉树,通过在每一层交替选择维度来划分空间,适用于高效的范围查询和最近邻搜索。

alt

R-Tree

R 树是一种用于多维空间数据的树形结构,广泛应用于地理信息系统(GIS)中,通过最小边界矩形(MBR)组织空间数据。

alt

其他数据结构及图

布隆过滤器

布隆过滤器是一种空间高效的概率数据结构,常用于测试一个元素是否属于某个集合。虽然可能出现假阳性(即报告元素存在但实际上不存在),但绝不会产生假阴性。

alt

二叉堆

二叉堆是一种高效的优先队列实现,支持快速的插入、删除和最小值提取,常用于调度算法和实时系统。二叉堆由一系列二叉树组成,这些树是相互链接的特殊树

alt

每个堆中的二叉树都遵循最小堆属性:节点的键值大于或等于其父节点的键值。此外,每个顺序只能有一个或零个二叉树,包括零阶。

以下示例二叉堆包含 13 个节点:

alt

Hash Array Mapped Trie (HAMT)

HAMT 是一种结合了哈希表和 Trie 树优点的数据结构,能够高效地存储和检索键值对,常用于实现高效的字典结构。

alt

Merkle Tree

Merkle 树是一种用于验证数据完整性的树形结构,它通过将数据组织成哈希值,并不断向上传递,广泛应用于区块链和分布式系统中,确保数据的一致性和完整性。

alt

最后:8 个数据库中常用的数据结构

alt

#牛客激励计划#
SAGIMA经验浅谈 文章被收录于专栏

虽然咱也不算啥大佬,但也是踩过坑、中过招的,我要是早点知道这些,不早就……早就……早就知道这些了嘛~

全部评论

相关推荐

01-19 20:06
已编辑
C++的上限非常高,但是分阶段性逐步学习是没有问题的,一步步的学,慢慢领悟,总有一天会熟练掌握的。C++ 语言的学习其实就三个阶段就好了:(1) 入门阶段这个阶段的学习主要是熟悉 C++ 语言的语法知识。在这个阶段要做到理解对象的思想方法,培养自己的编程思维能力。目标是可以开发一些像贪吃蛇这种简单的控制台小程序。(2) 进阶阶段进阶阶段的学习主要是要掌握 C++ 标准模板库(STL)、设计模式、数据结构基础以及 UI 界面开发、数据库开发等高级技能。在这个阶段是要达到可以开发复杂的程序,达到工作中 C++ 开发程序员的能力。(3) 应用阶段这个是实战阶段,要具备一定的综合性应用软件开发能力。这个阶段就是多观摩别人的项目,看人家的写法,模仿项目,学习其中的思想,一点点的积累,一步步形成自己的东西,厚积而薄发,慢慢你就会发现你也可以了。注意!下面都是超极干的干货一、入门阶段入门阶段的学习主要是熟悉 C++ 语言的语法知识。除了基础的变量、常量、关键字、数据类型、运算符、数组、函数、指针、结构体外,还要学习 C++ 的面向对象编程思想、命名空间 namespace、引用、函数扩展、类的封装、构造和析构、继承、多态、异常处理等内容。语言部分的学习建议不要拖太久,一定要规划好时间,一鼓作气,不然自己容易泄气!1.视频推荐此时同学们应该是毫无基础或者稍微有点 C 语言基础的小白。对于小白来说,不建议上来就看书,因为干看看不懂,容易劝退。可以先从视频教程开始,教材为辅。我当初 C++ 视频是在 b 站看的黑马程序员的 C++ 课程(我不是他们的托儿从 0 到 1 教 C++,三百多个小节,每个小节时间都不是很长,除了个别几个在二十多分钟,其余的基本上都在几分钟到十几分钟之间。每一个阶段都会有相应的小项目教学,对初学者来说是很友好的。看视频的时候不是看看就过去了,编程毕竟是门一门手艺活,孰能生巧。建议一边看,一边将视频中的示例或者小项目教学自己也实现一下,刚开始不会可以照着敲,比只看不动手强一百倍。此外,我最近发现深蓝学院出品的「C++ 基础与深度解析」课程也很不错,深入基础,讲解语法细节。从基础语法讲到 Modern C++,从面向过程开发到新编程范式,对大家学习 C++ 很有帮助。2.书籍推荐入门阶段的书籍为辅,怎么为辅呢?就是视频看完一个阶段,然后就可以去看书上对应阶段的内容,这样看书,一方面看书的时候会很快,容易理解,另一方面可以印证自己在看视频的时候一些不太理解的地方。入门阶段推荐两本书,一本薄的,一本厚的,都是超级经典的书籍。《Essential C++》《Essential C++》是一本内容不多但很实用的 C++ 入门书籍,这本书强调的是快速上手与理解 C++ 编程。主要围绕一系列逐渐复杂的程序问题,以及用以解决这些问题的语言特性展开讲解。你不只学到 C++ 的函数和结构,也会学习到它们的设计目的和基本原理。《C++ Primer Plus》&《C++ Primer》很多人 C++ 入门的时候会推荐《C++ Primer Plus》,很多人 C++ 入门的时候会推荐《C++ Primer Plus》,我当年先看的也是这本书,当年 C 语言除了学校的教材,我看的就是《C Primer Plus》。这本书怎么说的,讲的超级全面,甚至有点过于全面了,书中的例子和课后习题循序渐进,不夸张的讲所有的知识点可能都囊括进去了,作者可能为了怕大家学不明白,讲的巨细,甚至我感觉都有点啰嗦,造成这本书巨厚,字又巨小,看完感觉近视又加了几度。当时我学习的时候《C++ Primer》还是第 4 版,现在都到第 5 版了!《C++ Primer》堪称 C++ 语法学习的最权威书籍,非常全面地讲解了C++的语法以及C++11的各种新特性,看完之后真的帮助特别大!如果有时间建议至少看两遍以上!时面向 C++ 语言的初学者,是一本很友好的自学教材!而且例程和习题丰富,相信认真读过之后,可以完成 C++ 语言入门这个目标!!如果你在这个阶段觉得差不多了,可以尝试找一些在线的练习题做下,如果你不知道去哪找,那可以去下面这个初学者练习编程巩固语法的绝佳去处。它有专门的 C++ 入门编程练习题,专门练习语法和大家的编程逻辑,从变量、数据类型这些基础语法,到数组、字符串这种复合类型,再到函数、面向对象,以及在 C++ 中很重要的 STL,最后再来点综合练习,差不多 70 多道题,够你练的。除了编程练习以外,如果你想知道你自己的知识点掌握的如何,也可以做一下专项练习。以类似试卷的形式,可以很好的检验自己的学习成果,不管是对之后应对考试,或者应付笔试面试都很有帮助。二、进阶阶段在进阶阶段,你已经对 C++ 有一定的认知了。这个时候我们可以深入学习 C++ 标准模板库(STL)、设计模式、数据结构基础以及 UI 界面开发、数据库开发等高级技能。1.书籍推荐《C++标准程序库》关于 STL,可以先读这本侯捷老师翻译的《C++ 标准程序库》。通过这本书对STL有个基本认识,学会使用 STL。《STL源码剖析》读完 《C++ 标准程序库》,就可以来读这本侯捷老师编写的《STL源码剖析》了。这本书建议必读!这本书讲解了 C++ 底层实现,主要包括 C++ 底层内存管理、各种容器的数据结构实现、常见算法的实现等。可以帮助深入理解C++底层,同时也是对数据结构的复习和巩固。《Effective C++》《Effective C++》讲了 C++ 编程的 55 条准则,提高你的 C++ 编程质量,也是侯捷老师翻译的!这本书有助于梳理在编写 C++ 程序时的一些常见错误和注意事项,也是面试常考的。《深度探索C++对象模型》《深度探索C++对象模型》这本书讲解了C++面向对象特性的底层实现机制。侯捷老师翻译的,看完这本书,对C++面向对象的理解帮助极大,建议必读!2.视频推荐不知道大家注意了没,上面我推荐了四本书,都和一个人有关:侯捷老师。书要么是他翻译的,要么是他写的,C++ 领域 YYDS!同意吧?侯捷老师当然也有讲课,针对书都有对应内容的视频课程!三、应用阶段其实编程语言就是要多练,怎么多练,就是代码量。自己多写,然后多观摩别人的项目,看人家的写法,模仿项目,学习其中的思想,一点点的积累,一步步形成自己的东西,厚积而薄发,慢慢你就会发现你也可以了。面经可以参考c++面经 总结的很详细   https://daxprogram.com/
点赞 评论 收藏
分享
01-17 15:42
门头沟学院 Java
算是一家小型初创公司,ai相关,刚起步岗位需求多,投的后端实习岗,年后入职。面试官说有机会接触到一些算法上的东西,公司核心业务可以说是跟自己研究方向相关的,至少目前非常满意😊虽然难度低,也没深挖什么八股,但这次的面试状态是秋招以来最好的一次了(前一天晚上看了会儿今天不coding的直播,听同龄人分享各种经历,确实很大程度上缓解了内心的焦虑),可能也是由于面试形式是展示代码吧,对着自己的代码框框讲,就显得十分自信,面完几个小时后就发offer了。第一个项目是黑马点评,简单展示了一下用户登录,店铺信息缓存,优惠券秒杀的功能。提问:1. 在秒杀时,为什么要用lua脚本。    A:保证原子性2. 为什么选择caffeine做本地缓存    A:技术选型上没有什么考虑,只是知道有这么个技术,就用来练手了。使用caffeine时需要注意缓存一致性问题。3. 项目还有没有其他亮点    A:封装了redisson的布隆过滤器,结合redis缓存空值去避免缓存击穿。由于布隆过滤器是后期引入的,此时数据库已经有一百万条了(模拟的),通过多线程读取数据库中的数据,写入布隆过滤器,来加快布隆过滤器的构建。并利用自增的主键id解决深分页问题。4. 布隆过滤器的原理    A:bitmap,多个hash函数5. 布隆过滤器的缺点    A:误判,不支持删除6. 如何解决删除问题    A:定期重写布隆过滤器    这里面试官说这种方案不好,因为重写过滤器会影响到业务的使用,我提了可以在低峰期重写,但面试官还是不太满意。第二个项目是github上找的一个开源项目,主要关注了一下核心业务的实现,并做了一定的改进与拓展。由于时间原因,简单介绍了一下用rabbitmq异步将用户点赞记录写入数据库的实现。提问:用mq异步写入点赞数据,如果消费者效率慢,会导致前端页面反馈不及时,如何解决A:可以用redis缓存文章点赞数,并定期将mysql中记录的点赞记录数量同步到redis缓存中(当时这里没想好,随便答的。或者应该用redis的set来缓存点赞记录,并定期写入mysql?)反问环节略
查看7道真题和解析
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务