美团Android岗面试真题:手写红黑树详解

时间:2021-06-08 23:19:00   收藏:0   阅读:0

变态的面试题

前阵子发了一篇文,说了一下现在大厂对算法的重视,留言区很多人表示算法是一个过不去的坎。

技术图片

其中的一个朋友就发来了他面试美团Android岗的面经:

技术图片

他表示,其他的面试题目都答得还不错,面试官也很满意,但是这个手写红黑树把他难倒了,支支吾吾了半天也没有弄清楚,希望我能帮助他。

想着有这个问题的应该不止他一个,就决定写个文和大家分析一下这个红黑树,希望对大家的学习和工作有所帮助。

面试中的红黑树

隔热觉得,手写红黑树可能有点过分了,我觉得写不出来也正常,只要理解就行(面试的时候可以问问能不能改为口述)。

红黑树是数据结构中比较复杂的一种,最近与它交集颇多,于是花了一周的空闲时间跟它死磕,终于弄明白并实现了红黑树。

写文总结一下,希望能给试图理解红黑树的同学一些灵感,也让我能记得更深刻。

在研究红黑树时吃了不少苦头,原因有二:

网络上讲红黑树的实现多来源于《算法导论》一书,直接讲红黑树的实现,需要处理颜色和高度两种属性约束,比较晦涩。本文通过红黑树的等同—— 2-3-4树,避开颜色属性约束,也弱化了高度的影响,以另一种方式去理解红黑树,虽然并不能完全降低它的复杂度,但自认为较之普遍实现,更易记一些。

红黑树

红黑树是一种结点带有颜色属性的二叉查找树,但它在二叉查找树之外,还有以下要求:

  1. 节点是红色或黑色。

  2. 根是黑色。

  3. 所有叶子都是黑色(叶子是NIL节点)。

  4. 每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点。)

  5. 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。

下图就是一个典型的红黑树:

技术图片

但实现上我省略了其中的 Nil 结点,一般如下图,大家理解时也可以忽略它们。

技术图片

优势和用途

我们知道二叉查找树在不停地添加或删除结点后,可能会导致结点情况如下:

技术图片

这种情况下,二叉查找树的查找效率最坏会降低为 O(n)

而红黑树由于在插入和删除结点时都会进行变色旋转等操作,在符合红黑树条件的情况下,即使一边子树全是黑色结点,另一边子树全是红黑相间,两子树的高度差也不会超过一半。一棵有 n 个结点的红黑树高度至多为 2log(n+1),查找效率最坏为 O(log(n))

所以红黑树常被用于需求查找效率稳定的场景,如 Linux 中内核使用它管理内存区域对象、Java8 中 HashMap 的实现等,所以了解红黑树也很有意义。

下面介绍一下红黑树的等同 2-3-4树。


2-3-4树

2-3-4树是四阶的 B树(Balance Tree),它的结构有以下限制:

下图是一个典型的 2-3-4树(来自维基百科):

技术图片

2-3-4树的查询操作像普通的二叉搜索树一样,非常简单,但由于其结点元素数不确定,在一些编程语言中实现起来并不方便,实现一般使用它的等同——红黑树

对应红黑树

至于为什么说红黑树是 2-3-4树的一种等同呢,这是因为 2-3-4树的每一个结点都对应红黑树的一种结构,所以每一棵 2-3-4树也都对应一棵红黑树,下图是 2-3-4树不同结点与红黑树子树的对应。

技术图片

而上文中的 2-3-4树也可以转换成一棵红黑树:

技术图片

由红黑树的性质5,和 2-3-4树的性质1,为了便于理解红黑树和 2-3-4树的对应关系,我们可以把红黑树从根结点到叶子结点的黑色结点个数定义为高度

红黑树和 2-3-4树的结点添加和删除都有一个基本规则:避免子树高度变化,因为无论是 2-3-4树还是红黑树,一旦子树高度有变动,势必会影响其他子树进行调整,所以我们在插入和删除结点时尽量通过子树内部调整来达到平衡,2-3-4树实现平衡是通过结点的旋转和结点元素数变化,红黑树是通过结点旋转和变色。

下面来对照着 2-3-4树说一下红黑树结点的添加和删除:


结点插入

2-3-4树中结点添加需要遵守以下规则:

而将这些规则对应到红黑树里,就是:

技术图片

如上图所示,虽然向红黑树中插入了一个新结点,但由于旋转和变色,子树的高度保持不变。


删除结点

红黑树的删除要比插入要复杂一些,我们还是类比 2-3-4树来讲:

将这些规则对应到红黑树中即:

技术图片

如上图,删除的要点是 找到替代结点,如果替代结点是黑色,递归向上依次判断侄子结点、父结点是否可以补充被删除的黑色,整体思想就是将删除一个黑色结点造成的影响局限在子树内处理。


小结

当然实现过程中调试也占了很大一部分,我使用了两项方法帮助调试:

由于红黑树相对其他树实在较为复杂,只通过思考就完全理解不太现实,还需要自己去试着画,试着实现,我画了 5 张 A4 纸的正反面才算理解了红黑树,即便如此,在写这篇文章时还发现了代码中的可优化点。

而且代码实现比画图还略复杂,理论中的一个旋转就包含了 左旋/右旋/先左旋再右旋/先右旋再左旋 几种情况,虽然有一定规律,还是自己实现一下印象最深刻。

笔者感想

算法现在真的是越来重要了,已经成为一个考验程序员技术水平最快的方法,尤其是对应届生来说。听说字节跳动的技术岗甚至有算法题一票否决的情况。

但是,数据结构与算法这个知识点的准备需要的时间比较长,要尽早准备,多刷一些leetcode或是其他类似的题。我个人的算法能力一开始也很差,但是经过我自己安排的算法专项训练,效果还是十分显著的。下面是我的复习方法,希望对大家的学习和工作有所启发和帮助。

算法复习和学习经验分享

下面是数据结构和算法的面试核心知识点,大家可以参考学习,逐个击破。

在刷题之前我建议你看一些书:

《漫画算法之旅》
技术图片

如果你之前没有任何算法基础,这边书很适合你,可以补充数据结构和算法的基础知识,像什么是时间复杂度空间复杂度、查找、排序等。
如果你有了一定基础了,建议你直接跳到最后面的算法实战部分。

《剑指 offer》

技术图片

非常经典的一本书,学算法的人必刷。但是要注意了,这边书里面的题目是用 C++写的,如果你是 Java 开发人员可能会有点影响。但是要记住学习算法最关键的还是解题思路和方法,用什么语言实现是其次的,如果你时间比较多我是建议你用 Java 语言再实现一遍。

《labuladong的算法小抄》

技术图片

非常推荐!这是一本很新的书,写书前作者在 Github 开源了一个项目,主要讲解 LeetCode 解题套路,Start 总数排名前40。在书的开头讲解了学习算法的基本思维和套路,建议看这边书的同时再配合 leetcode 刷题,疗效非常棒!

《算法导论》

技术图片

要是不推荐这本书是不是显得我有点 low 了,这是一本科班出身的同学必看必学的经典大部头。国外大佬写的,国内翻译的经典之作,虽然是经典但是不建议刚入门算法的同学看,因为看了这本书你可能要放弃算法了,比较难看懂。建议有了一定基础再入手这边书。

如果你觉得看书比较枯燥,可以推荐你看一些极客时间的专栏,不过是收费,但是质量非常高。

《数据结构与算法之美》

技术图片

这个专栏是文字+语音,作者是王争,前 Google 工程师。他采用最适合工程师的学习方式,不拘泥于某一特定编程语言,从实际开发场景出发,由浅入深教你学习数据结构与算法的方法,帮你搞懂基本概念和核心理论,深入理解算法精髓,帮你提升使用数据结构和算法思维解决问题的能力。

《算法面试通关40讲》

这个专栏是视频,作者是覃超,前Facebook工程师。作者会用白板带你一步一步解题,层层深入一环扣一环,每一题还会用多种解题方法。我基本看完了,收获颇多。

leetcode、书和极客专栏可以并行,学练结合,不要光看不练。

点击【此处】进入我的公众号,添加备注【算法】,免费获取这份资料的完整版

B站免费学习视频

最后

这边还整理了一套大厂常问Android面试真题,有需要的朋友可以找我一起打包获取。

点击【此处】进入我的公众号,添加备注【算法】,免费获取这份资料的完整版

技术图片

技术图片

资源持续更新中,欢迎大家一起学习和探讨。

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!