浅谈红黑树——java面试拦路虎

红黑树相信经过面试官折磨的人都不会太陌生,作为数据结构中较复杂都一种,一直是面试中面试官常用的虐杀手段。废话不多说,直接进入正题。

在了解红黑树之前,先要了解二叉查找数,又叫二叉树。二叉树顾名思义,是一种每个节点最多有两个子节点都树,同时遵循 左节点的值<父节点的值<右节点的值 这样的规律,如下图所示。

它是一种查找次数小于等于树高的数据结构。如图中树有4层,即树高为4,当我们需要查找8时,经过的路线是这样的:

1、8<9,往左查找

2、8>5,往右查找

3、8>7,往右查找

4、8=8,找到结果

总共查找4次,等于树高。这棵树不管怎么找,查找次数总是小于等于树高。

二叉树的插入同样遵循上述规则,会一步一步对比,从而找到插入的位置,可以想象上图中的8不存在,而是需要插入一个8,结果与上述路线一致。

二叉树的删除会涉及到无子节点和有子节点两种情况,无子节点直接删除即可,有子节点会需要用左边最大值或右边最小值替换当前删除节点,具体不细聊。

当二叉树插入数值不均衡时,会出现树结构的变形与查找性能的损耗,比如现在二叉树有8,9,12三个值,然后需要插入7,6,5,4,3这五个值时,产生的结构如下图所示。

树高会不合理的增高,查找效率也无法得到保证。红黑树就是为了解决这种情况而诞生的。

红黑树又称为自平衡二叉树,它符合二叉树的规则同时比它的规则更加的复杂,具体规则如下:

1、所有节点都是红色或黑色

2、根节点为黑色

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

4、每个红色节点必须有两个黑色的子节点。(不能有两个连续的红色节点。)

5、从任一节点到其每个叶子的所有简单路径(不要回退)都包含相同数目的黑色节点。

具体样子如下图所示:

解释一下几个规则的含义:

1,2很好理解,节点都是红和黑,根节点是黑色的。

3所有叶子都是黑色的,叶子与叶子节点是两个概念,叶子不是一个节点,可以理解为没有数值的空节点,也就是图中的NIL。

4也很好理解,红色节点的子节点都是黑色的,这就保证了没有两个连续的红色节点。

5稍微解释一下,简单路径就是说一次到底,不要回退,叶子就是NIL,比如从8这个节点出发,不管是去1下面的叶子,11下面的叶子,还是6下面的叶子,都是经过一个黑色节点,从任何节点出发都是一样的规则,经过相同数量的黑色节点。

以上5个规则,加上二叉树的规则,就组成了红黑树这一极具特点的树型数据结构。

红黑树的查找与二叉树类似,都是查找次数小于等于树高,但红黑树由于平衡的规则会使树高相对平衡,不会出现某条路径远远大于其他路径的情况。

红黑树的插入较为复杂,有时为了维持规则需要做结构的调整,常用的调整手段是改变颜色、左旋转和右旋转。由于规则5,如果插入的值为黑色节点,会导致黑色节点数量很难相同,所以默认每次插入的值都为红色节点。和二叉树一样,通过对比找到插入的位置,默认插入一个红色节点的数值,这里会分为很多情况,大概列举如下:

1、插入位置为根节点(第一个值),红色变成黑色即可。

2、插入位置父节点为黑色节点,直接插入一个红色节点即可。此时1,2,3规则都不会违背,由于父节点为黑色,4也没有违背。由于插入的是红色节点,5也没有违背,所以红黑树不需要做调整,直接插入即可。

3、插入位置父节点与父节点的同级节点(下称叔父节点)均为红色节点,需要改变父节点和叔父节点的颜色为黑色,同时将父节点的父节点(下称祖父节点)改变为红色。如果祖父节点为根节点或祖父节点的父节点也为红色,需要进一步变化。可以理解为把祖父节点带入这个方法逻辑中,类比为插入祖父节点,从而判断祖父节点需要如何变化。

4、插入位置父节点为红色,叔父节点为黑色或者空节点,同时新增节点是其父节点的右子节点而父节点又是其父节点的左子节点时,需要使用到左旋转,如图所示。N为插入的节点,P为它的父节点。左转换逆时针旋转P节点与它的两个子节点,同时将N节点下的2节点给到P节点。两个红色一起违反规则4,可再将N节点变更为黑色。

5、插入位置父节点为红色,叔父节点为黑色或者空节点,同时新增节点是其父节点的左子节点而父节点又是其父节点的左子节点时,需要使用到右旋转,如图所示。N为插入的节点,P为它的父节点,G为P的父节点。右转换顺时针旋转N,P,G三个节点,同时将P节点下的3节点给到G节点。再改变P和G的颜色即可。

6、插入位置父节点是其父节点的右子节点时,与上述4,5情况完全相反,即只要将4和5中的所有左换成右,所有右换成左,就是这种插入情况的处理方法。

红黑树的删除同样复杂,删除的节点有各种各样的情况,但我们可以统一类化为删除的节点只有一个子节点的情况。如果删除的节点有两个子节点,与二叉树类似,红黑树也是需要找到左子树中的最大值或右子树中的最小值,将数值做替换,等于删除的是左子树中的最大值或右子树中的最小值,这个值一定不会有两个子节点,而只是数值的替换,颜色保持不变,所以不会破坏规则。如果删除的节点没有子节点,可以将一个空节点当成它的子节点。所以我们只需要考虑删除的节点只有一个子节点的情况。

1、删除节点为红色的情况。删除节点为红色,根据规则4,它的儿子一定是黑色,此时只要删除当前节点即可,它的儿子是黑色,所以不会破坏规则3和4,同时路径中只是缺少了一个红色的节点,也不会破坏规则5.

2、删除的节点为黑色,它的儿子是红色的情况。这种情况也很简单,将当前节点删除,将它的儿子从红色改变成黑色即可。

3、删除的节点为黑色,它的儿子也是黑色的情况。这种情况比较复杂,暂时不介绍了,可看维基百科对红黑树的介绍。

红黑树的结构、规则和实现方式大致介绍完了。面试中经常会问的大概就是结构与规则,以及它的平衡方法,改变颜色、左旋转和右旋转。还需要了解它的时间复杂度O(logn)、应用场景与好处。想要更多了解可以参考维基百科对红黑树的介绍,还是非常详细的。

原文地址:https://www.cnblogs.com/dtt-java/p/12228642.html

时间: 2024-10-11 15:54:55

浅谈红黑树——java面试拦路虎的相关文章

浅谈红黑树(C语言代码实现)

定义: 我们先来看看<算法导论>中的红黑树的定义:"红黑树是许多'平衡'搜索树的一种,可以保证在最坏的情况下基本动态集合操作的时间复杂度为O(lgn)." 性质: 红黑树的性质如下: 1.每个节点是红色的,或者是黑色的. 2.根节点和叶子节点是黑色的. 3.如果一个节点是红色的,那么它的父节点和子节点必须是黑色的. 4.对于每一个节点来说,从该节点到叶子节点的简单路径上,所包含的黑色节点的数量必须一致. 节点属性: 红黑树每个节点的基本属性值有五个: 1.color:表示该

浅谈红黑树的添加删除操作

红黑树的性质(牢记) 1.每个结点的颜色只能是红色或黑色. 2.根结点必须是黑色的. 3.每个叶子结点都带有两个空的黑色结点(被称为黑哨兵null),如果一个结点n的只有一个左孩子,那么n的右孩子是一个黑哨兵:如果结点n只有一个右孩子,那么n的左孩子是一个黑哨兵. 4.如果一个结点是红的,则它的两个儿子都是黑的.也就是说在一条路径上不能出现相邻的两个红色结点. 5.从任何一个结点到其子孙叶结点的所有路径上包含相同数目的黑结点. 一.红黑树的插入 任何一个即将插入的新结点的初始颜色都为红色.这一点

浅谈红黑树

红黑树是什么? 其实也是平衡二叉树,只是给每个节点标了红黑颜色 为什么需要红黑树? 红黑树其实基础还是二叉查找树,只是因为二叉查找树很容易出现不平衡的情况,最坏情况相当于O(n),红黑树和AVL树应运而生,AVL树的话,因为平衡度要求是[-1,1]太严格,所以插入和删除的时候的效率并不是很高,比不上红黑树,但是因为平衡度是[-1,1],所以查找速度比红黑树快,AVL适用于频繁查找,红黑树适用于频繁插入和删除 红黑树五大特性 1,每个节点不是黑色就是红色 2,根节点肯定是黑色 3,叶子节点肯定是黑

转:最近5年133个Java面试问题列表

最近5年133个Java面试问题列表 Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别就能让你直接进入第二轮面试,但是现在问题变得越来越高级,面试官问的问题也更深入. 在我初入职场的时候,类似于 Vector 与 Array 的区别.HashMap 与 Hashtable 的区别是最流行的问题,只需要记住它们,就能在面试中获得更好的机会,但这种情形已经不复存在.如今,你将会被问到许多 Java 程序员都没有看过的领域,如 NIO,

java 面试 -- 4

Java面试知识点总结 本篇文章会对面试中常遇到的Java技术点进行全面深入的总结,帮助我们在面试中更加得心应手,不参加面试的同学也能够借此机会梳理一下自己的知识体系,进行查漏补缺(阅读本文需要有一定的Java基础:若您初涉Java,可以通过这些问题建立起对Java初步的印象,待有了一定基础后再后过头来看收获会更大).本文的问题列表来自于http://www.nowcoder.com/discuss/3043,在此感谢原作者的无私分享:) 1. Java中的原始数据类型都有哪些,它们的大小及对应

Java面试宝典

http://www.cnblogs.com/bluestorm/p/6429894.html Java面试宝典 面向对象的三个特征 封装,继承,多态.这个应该是人人皆知.有时候也会加上抽象. 多态的好处 允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用).主要有以下优点: 可替换性:多态对已存在代码具有可替换性. 可扩充性:增加新的子类不影响已经存在的类结构. 接口性:多态是超累通过方法签名,想子类提供一个公共接口,由子类来完善或

网上整理的Java面试

1:static关键字什么意思?Java中是否可以覆盖(override)一个private或者static的方法? static关键字表示一个成员变量和成员方法可以在没有类的实例变量情况下被访问.Java中的static方法不能被覆盖,因为方法的覆盖是运行时动态绑定的,而static方法是编译时静态绑定的.static方法跟类的实例不相关的. 2:是否可以在static环境中访问非static变量? static变量是属于类的.当类被虚拟机加载时,会对static变量进行初始化,但是此时非st

java面试(2)--大数据相关

第一部分.十道海量数据处理面试题 1.海量日志数据,提取出某日访问百度次数最多的那个IP. 首先是这一天,并且是访问百度的日志中的IP取出来,逐个写入到一个大文件中.注意到IP是32位的,最多有个2^32个IP.同样可以采用映射的方法, 比如模1000,把整个大文件映射为1000个小文件,再找出每个小文中出现频率最大的IP(可以采用hash_map进行频率统计,然后再找出频率最大 的几个)及相应的频率.然后再在这1000个最大的IP中,找出那个频率最大的IP,即为所求. 或者如下阐述(雪域之鹰)

Java面试必问之---HashMap

本文有些长,贴的源码较多,请各位看官自备花生瓜子啤酒饮料矿泉水小板凳,且听我慢慢道来. Java面试都会问集合,集合必问HashMap,CurrentHashMap,后面的套路就肯定会问多线程.线程安全等等,今天就来学习下HashMap,不对,是补习下. 1.HasMap的属性 先看下HashMap的继承体系,它继承自抽象类AbstractMap,实现了Map.Cloneable.Serializable接口,还有较常用的子类LinkedHashMap也实现了Map接口. public clas