简单理解红黑树

在升级到JDK8之后,HashMap在列表个数大于8个时候,采用了红黑树来实现。面试的时候经常会问到我们一些红黑树的问题。那么我们首先要知道什么是红黑树。

红黑树性质定义

红黑树也是二叉查找树,我们知道二叉查找树的结构并不难,而红黑树就是难在它是自平衡的二叉树。它必须满足以下性质:

1.每个节点要么黑色要么红色。

2.根节点必需是黑色。

3.每个叶子节点(NIL)是黑色。

4.每个红色节点的两个子节点一定都是黑色。

5.任意一节点到每个叶子节点的路径都包含了数量相同的黑色节点。

我们知道在由随机数节点组成的二叉树的平均高度为logn,所以正常情况下二叉树查找的时间复杂度为O(logn)。但是,根据二叉树的特性,在最坏的情况下,比如存储的是一个有序的数据的话,那么所以的数据都会形成一条链,此时二叉树的深度为n,时间复杂度为O(n)。红黑树就是为了解决这个问题的,它能够保证在任何情况下树的深度都保持在logn左右。为什么这么说呢,我们由他的性质总结出一个隐含性质:从根节点到叶子节点的最长路径不大于最短路径的 2 倍。

红黑树的增加和删除

我们在将红黑树的增加和删除的时候首先要了解3种操作

1.变色:节点的颜色由红色变为黑色或者黑色变为红色。

2.左旋:以某个节点为旋转点,其右子节点变为旋转点的父节点。右子节点的左子节点变为旋转点的右子节点,旋转点的左子节点保持不变。如下图

3.右旋:以某个节点为旋转点,其左子节点变为旋转点的父节点,左子节点的右子节点变为旋转点的左子节点,旋转点的右子节点保持不变。如下图。

了解这些操作之后我们来看下红黑树的插入。红黑树的插入分为两部分,一是找到查找位置,二是插入后自平衡。查找插入位置我们就不细说了,跟二叉树是一样的。有性质5知道,当前红黑树中从根节点到每个叶子节点的黑色节点数量是一样的,此时假如新的是黑色节点的话,必然破坏规则。但加入红色节点却不一定,除非其父节点就是红色节点,因此加入红色节点,破坏规则的可能性小一些。所以每次插入节点的颜色为红色

现在我们将红黑树插入情景做以下分类,并对每个情景做自平衡分析。

情景1:红黑树是空树。将插入节点作为根节点,并将其置为黑色。

情景2:插入节点的Key已经存在,则将该存在的节点的value替换为插入节点的value。

情景3:若插入节点的父节点为黑色则直接插入该节点。

情景4:插入节点的父节点为红色又可以分为几种情况。

为了理解简单我们定义,其中C为要插入节点。P为要插入的父节点。PP表示祖父节点,S表述叔叔节点。

 

情景4.1   S节点存在且为红色。

将P节点和S节点都置为黑色,将PP置为红色。

若PP为根节点,那么我们将PP再置为为黑色。

否则把PP当做前要插入节点,再去判断其父节点是什么颜色。若PP节点的父节点为黑色,则不需再做任何处理。

若为红色,则还需要将PP当做要插入节点做自平衡处理。

情景4.2  S节点为黑色或者不存,且P节点是PP节点的左子节点,C节点要插入为P节点的子节点又分为两种情况。

此时必须说明,若S节点不存在即为NIL节点。若S节点存在且为黑色节点,那么因为P节点是红色所以PP节点必不能为根节点且有相邻节点。相邻节点必存在一个黑色节点才能不违反性质。

4.2.1:若C是P的左子节点,那么先将P变为黑色,再将PP变为红色,将PP进行右旋。

4.2.2.若C是P的右子节点,那么先将P进行左旋,将P作为插入节点,再按照4.2.1进行操作。

情景4.3 P节点为黑色或者不存在,S节点是PP节点的右子节点,C节点要插入为S节点的子节点又分为两种情况。

4.3.1  若C是S的右子节点,那么先将S变为黑色,再讲PP变为红色,将PP进行左旋。

4.3.2  若C是S的左子节点,那么先将S节点右旋,将S作为插入节点,再按照4.3.1操作。

红黑树的插入分析完后,我们再对红黑树删除进行分析(待续)。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值