红黑树的描述与解析

今天我们来了解一下红黑树的结构特性与优势对比,在这之前我们首先应该知道二叉查找树和AVL树:
二叉查找树:
1.左子树上所有结点的值均小于或等于它的根结点的值。

2.右子树上所有结点的值均大于或等于它的根结点的值。

3.左、右子树也分别为二叉排序树,如下图:
在这里插入图片描述
这就是一棵简单的二叉查找树,从上面的图中可以看出他也是一棵简单的排序二叉树,但这种情况会产生一种最坏的情况当重新组合这些数让他们上来就按照一定顺序进行排序再插入,这样就破坏了他的平衡,成了一个所谓的“单一”生物,如图:
在这里插入图片描述
此时我们便加入了平衡二叉树(AVL)来解决他的平衡问题,它规定所有路径与最短路径之间的差值不能超过1的绝对值,因为他便是特殊的二叉树,他属于完全平衡的二叉排序树,在进行插入或删除的过程中,他会判断是否差值在1的绝对值范围内,他的时间复杂度为O(logN),但在插入与更新操作上不如红黑树,因为红黑树追求的是部分平衡,而非严格的完全平衡。这是便提出了红黑树的思想。

红黑树的特性

1.根节点一定为黑色。
2.没有两个连续的红色节点
3.每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
4.每个节点不是红色就是黑色。
5.如果一个节点为红色,那么他的子节点一定为黑色。
6.每条路径的黑色节点的数目是一致的。

在这里插入图片描述
这便是一棵最经典的红黑树,他是一个自平衡的二叉树结构,他和AVL最大的不同是它不需要完全平衡,而是部分达到平衡即可,这样也就大大提高了插入与更新的性能的要求,而在插入的时候他也是遵循一定的规则而进行操作的,也就是我们听闻的变色旋转

红黑树操作------变色

我们规定当进行插入操作的时候,插入的节点默认规定为红色,就会造成如下结果在这里插入图片描述

从图中我们可以看出当插入一个节点为18的红色节点,但通过观察你会发现,他的父亲节点19和他的叔叔节点26都为红色,此时我们就需要进行变色操作,根据变色要求:

1.先把插入红色节点的父节点和叔叔节点变为黑色
2.把插入节点的爷爷节点25变为红色
3.此时把指针定义移至爷爷节点继续判断,此时只要保证满足红黑树基本特性即可

我在变色的时候遇到一个问题,当变色到根节点的子节点为黑色的时候根节点无法满足变为红色来解决(因为会出现有两条路径的黑色节点变为4的情况),所以此时仅仅用变色已经不能满足红黑色特性,这时候就会用到我们下面的旋转了。

红黑树操作------旋转

左旋转
在进行左旋转的时候需要观察当前插入节点的父节点是否为红色,而叔叔节点是否为黑色节点,满足这两个条件之后,再观察插入节点是否在父节点的右子树位置。
在这里插入图片描述
这便是左旋的操作,结合上面的变色过程图来讲解一下在这里插入图片描述
此时就需要运用上面左旋的操作把根节点换成17,把节点15进行左旋转移动到13下面变为右节点,然后进行一次变色操作就形成右面的局势,但你以为这样就完了?你细看会发现有条路径的黑色节点数目已经为4了,所以根据实际需求我们还需要进行一次右旋转操作,让17-13-8-1-6的层数减少。

右旋转
右旋转和左旋转的判断方式一样,根据实际需求,如果仅仅在插入红色节点上进行判断的话,仅需要清除他的父亲节点是否为红色,而叔叔节点是否为黑色即可,
在这里插入图片描述

具体问题具体分析,接下来让我们来解决上面所出现的黑色节点超数的问题
在这里插入图片描述
此时我们就可以看到把13变为8的右子节点,10进行右旋转整体变为13的左节点即可,此时根据特性仅仅需要进行一次简单的变色便可达到黑色节点数相同的情况。
在实际开发中的JDK的集合类中TreeMap和TreeSet的底层都运用到了红黑树的性值,而在JDK1.8中HashMap结构也从数组+链表的形式改为数组+链表+红黑树的形式来存储数据。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值