在面试官面前优雅地种下红黑树

简介: 希望面对面试官的各种红黑树的灵魂拷问时,也能像标题一般,优雅地娓娓道来。

f5c3553357b746f48006c4781eb91fad.png


前言


       

希望面对面试官的各种红黑树的灵魂拷问时,也能像标题一般,优雅地娓娓道来。


一、红黑树的基本性质


     

先简单地说一下红黑树的规则:


1、根节点为黑色

2、叶子节点(值为NULL的节点)为黑色

3、红色节点的子节点为黑色

4、新插入的节点为红色

5、从一个节点访问到叶子节点,任意一条路径上黑色节点的数量相同


二、为什么要用红黑二叉树



面试官也会有其他的问法:“为什么有了BST和AVL,还要用红黑树呢?”想要清楚地回答这些问题,就要先了解二叉搜索树和二叉平衡搜索树。


1、 二叉搜索树(Binary Search Trees)


所谓二叉搜索树,可提供对数时间的元素插入和访问。二叉搜索树的节点放置规则是:任何节点的键值一定大于去其左子树中的每一个节点的键值,并小于其右子树的每一个节点的键值。

1a1dfdc7f7724795b430f5dd041248f0.png


可以看到,二叉树的插入、查询数据时,只需要和每一层的一个数据比较就行了,这就说明,插入和查询的时间复杂度取决于树的高度。


缺点: 当插入的数据有序时,二叉树会退化为一个链表,查询或插入的时间复杂度降为logN


747125b8a5054bedb2315bd77a48eecd.png


2、二叉平衡搜索树(Balanced binary search trees)


为了解决BST的缺点,AVL应运而生。        

AVL的性质:


1、拥有二叉树的全部特性;

2、每个节点的左子树和右子树的高度差不超过1;

3、左右两个子树都是一棵平衡二叉树

ca703aa717d1461e92693f3fd42b8425.png


为了满足第二点性质,平衡二叉树的节点不会出现一边倒的情况,但是需要做大量的操作(左旋、右旋等)来满足这一条件,使得其最坏情况下查找的时间复杂度也还是为O(logn)。


AVL树的构建这里就不多赘述了,我们主要来讲红黑树。


3、 总结:为什么要用红黑树


用一句话来概括就是:BST会退化为链表,AVL太麻烦,红黑树是一个折中的办法。


虽然AVL树解决了二叉搜索树退化了近似链表的缺点,但是由于每个节点的左子树和右子树的高度差不超过1这个要求实在是太严苛了,导致每次插入和删除节点的时候很容易就破坏了这条规则,之后就需要左大量的左旋和右旋来进行调整时期再次符合AVL树的要求。


所以如果在插入和删除很频繁的场景中,AVL树需要很频繁地进行调整,这样的话效率就大大降低了,为了解决这个问题所以出现了红黑树。(如果在面试中接下来这里就可以说出红黑树的那5个特点)。


正由于红黑树的这些特点,使其最坏情况下不仅还能维持用O(logn)的时间复杂度找到某个节点,而且与AVL树相比,优势就在于不会那么频繁地破坏红黑树的规则,从而不用那么频繁地进行调整,这就是我们大多数情况下使用红黑树的原因。


所以红黑树是一种相对AVL树来说不那么严格的平衡树,也就是一种折中的方案,介于普通的二叉搜索树和AVL树之间。极端情况下左右子树的节点数(也就是深度)相差一倍,也就是左边都有黑节点,右边都是红黑相间,右子树的节点数或者说深度就也是左子树的2倍,这个要求就比AVL树的相差最多只能为1宽松多了,因此调整也就更少,效率也就更高。


ee2d609f83cf468fbbb9016f158b9231.png


三、红黑树的插入



插入的节点为红色节点,而要满足红黑树的那5个性质,就需要旋转和变色,先说一下旋转和变色的规则,表格来自B站UP主free-coder(尊重一下知识产权):

d0121f50bec64592bb190ecfc6ff2aa3.png

可能乍一看表格还看不太懂,那么我们来根据表格把所有的情况都解释一下:


1、父节点为黑色


3f2370ba754a410681e865f649bf429d.png

直接插入即可


2、父节点为红色,叔叔节点为红色


先看一下完整过程,再分解步骤

cf7c6a5697b7489fa293db834c924fa8.png


(1)原树


8f81a6e236bc40cabdaf36951a57bf39.png

(2)加入新节点

42c71f77ba1e4c6d97a70cdcd30edbd8.png

(3)父、叔变黑,祖父变红

d93bbdefaa32468898ababaad5fb9981.png


(4)将祖父节点看作新插入节点,递归表格中的规则(这里祖父节点为根节点,所以变为黑节点了)

aed18b09a468439cbf4ed515b0034a11.png

3、父节点为红、叔叔节点为黑,新节点是祖父节点的右子节点的右子节点(上表中的:右右)


新增节点的父节点为20,红色;叔叔节点为null叶子节点,黑色。

0c4a6e37abda4633b9ea1de6e3794241.png


4、 父节点为红、叔叔节点为黑,新节点是祖父节点的左子节点的左子节点(上表中的:左左)


其实和3是对称的。


f0c5efc6f9fa40eca474a48b61692263.png


5、 父节点为红、叔叔节点为黑,新节点是祖父节点的右子节点的左子节点(上表中的:右左)

2e0d8a68aa154106ab8923d55705286a.png


在第一次右旋之后,就变成了3中的情况。


6、 父节点为红、叔叔节点为黑,新节点是祖父节点的左子节点的右子节点(上表中的:左右)


和5中对称。经过一次左旋之后,变成4中情况,再进行一次右旋后,变色。


cf0fc2a6a04e4f54a24284f7d8bfc645.png



四、删除节点



等我强大一点再来吧(肝不动了~~~~)

 

五、红黑树的应用场景



1、JDK的HashMap、TreeMap和TreeSet

2、Linux内核的虚拟内存管理

3、Nginx的Timer管理

4、C++的STL


这里要注意,如果面试官问到这个问题,你回答HashMap中用过,那下一步多半是要问问你HashMap中怎么用的,接下来可能就是问HashMap的原理……。所以回答这些名词的时候一定要确保自己顶得住接下来可能出现的夺命连环问,千万不要贪多只背这些名字。  


六、结尾



种下的不仅是红黑树,更是对offer的憧憬。

参考:红黑树,这次终于拿下了

相关文章
|
2月前
|
存储 算法 安全
HashMap常见面试题(超全面):实现原理、扩容机制、链表何时升级为红黑树、死循环
HashMap常见面试题:红黑树、散列表,HashMap实现原理、扩容机制,HashMap的jd1.7与jdk1.8有什么区别,寻址算法、链表何时升级为红黑树、死循环
|
4月前
|
Java
【Java集合类面试十一】、HashMap为什么用红黑树而不用B树?
HashMap选择使用红黑树而非B树,是因为红黑树在内存中实现简单,节点更小,占用内存少,且在插入、删除和查找操作上提供更好的平衡性能。
|
存储 编译器 C++
【C++从0到王者】第三十五站:面试官让手撕红黑树,我直接向他秀一手手撕map与set
【C++从0到王者】第三十五站:面试官让手撕红黑树,我直接向他秀一手手撕map与set
81 0
|
Java
|
存储 算法 数据可视化
35+,如果面试让我手写红黑树!
为啥,面试官那么喜欢让你聊聊 HashMap?因为 HashMap 涉及的东西广,用到的数据结构多,问题延展性好,一个 HashMap 就能聊下来80%的数据结构了。而且面试 HashMap 能通过你对红黑树的了解定位出你哪个级别的研发人员。
240 0
|
算法 NoSQL Redis
面试官:为何Redis使用跳表而非红黑树实现SortedSet?(下)
面试官:为何Redis使用跳表而非红黑树实现SortedSet?
158 0
面试官:为何Redis使用跳表而非红黑树实现SortedSet?(下)
|
存储 NoSQL Java
面试官:为何Redis使用跳表而非红黑树实现SortedSet?(中)
面试官:为何Redis使用跳表而非红黑树实现SortedSet?
172 0
面试官:为何Redis使用跳表而非红黑树实现SortedSet?(中)
|
存储 NoSQL Java
面试官:为何Redis使用跳表而非红黑树实现SortedSet?(上)
面试官:为何Redis使用跳表而非红黑树实现SortedSet?
306 0
面试官:为何Redis使用跳表而非红黑树实现SortedSet?(上)
java面试-彻底搞懂红黑树
红黑树性质 1、每个结点或是红色的,或是黑色的 2、根节点是黑色的 3、每个叶结点(NIL)是黑色的 4、如果一个节点是红色的,则它的两个儿子都是黑色的。
2202 0
Java面试必知词汇:红黑树
红黑树本质上是一种二叉查找树,但它在二叉查找树的基础上额外添加了一个标记(颜色),同时具有一定的规则。