红黑树

红黑树同样是一种二叉平衡搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。

红黑树的性质
1.对于任意一个结点而言,它要么是红色,要么是黑色
2.无论什么情况下,如果根节点,则根节点一定为黑色
3.对于任意一个结点,红色和红色不能相邻,即如果一个结点是红色的,则它的两个孩子和它的父结点都一定是黑色的。
4.对于任意一个结点,从该结点到其后代所有叶结点的简单路径上,均包含相同数目的黑色结点
5.红黑树中,null 位置看作是黑色

在这里插入图片描述

由上我们可以知道,对于红黑树中的任意路径(从根到null)。一头一尾必须是黑色的,红色不能相邻,黑色数量还要一样多,那么路径中最短的一条路径一定是一个红色都没有,最长的一条路径一定是每两个相邻的黑色中插入一个红色。所以红黑树中最长的路径的长度不会超过 最短的路径的两倍

红黑树结点的定义:

class RBTreeNode{
	RBTreeNode left = null;
	RBTreeNode right = null;
	RBTreeNode parent = null;
	COLOR color = RED; // 节点的颜色
	int val;
	
	public RBTreeNode(int val){
		this.val = val;
	}
}

在这里插入图片描述
由此可以保证红黑树具有相对的平衡,虽然不像 AVL 树那样绝对的平衡,但基本也可以看作是以 O(log(n)) 时间复杂度进行查询,且一定不会退化成单只树O(n).

我们同样主要讲述AVL树的插入,且在插入规则中保持红黑树的特征
1.按照搜索树的特征进行插入,且新插入的结点一定是红色的
2.插入的时候,一定要注意红色不能相邻
3.随着插入的完成
(1)插入的结点是根结点,则把结点改为黑色,插入完成
(2)插入结点的父结点是黑色,插入完成
(3)插入的结点的父结点是红色的,破坏了红色不能相邻的规则,所以修复

规则破坏的修复:
情况一,uncle(插入结点的祖父节点的另一个孩子)是存在的,且uncle为红色,如下情况:
在这里插入图片描述
修复的规则:仍然要保证这两条路径上只有一个黑色
修改的方式为:
grandpa由黑色变成红色
parent和uncle由红色变成黑色

如下:
在这里插入图片描述
可见,每条路径上仍然只有一个黑色,但是由于grandpa变成了红色,所以我们还需要往上蔓延。考虑grandpa和它父结点的问题,所以我们还需要要将cur设置为grandpa

cur = grandpa;
parent = cur.parent;
grandpa = parent.parent;

按照同样的规则继续检查,直到所有结点都满足红黑树的特性

情况2:uncle不存在,或者uncle存在但uncle为黑色
情况2.1:cur 是parent 的左边,并且parent是grandpa的左边
在这里插入图片描述
可以发现当uncle是黑色时,各路径黑色数量不一样多,所以parent插入之前一定是有子树的,并且两边子树中至少有一层黑色

修复方式:对grandpa进行右旋,然后将parent变成黑色,grandpa变成红色
在这里插入图片描述
在这里插入图片描述

情况2.2:cur 是parent 的右边,并且parent是grandpa的右边
同理解决:对grandpa左旋,parent变黑,grandpa变红

情况2.3: cur 是parent 的右边,并且parent是grandpa的左边
在这里插入图片描述

处理方式为:对parent左旋,然后将原来的cur视为parent,将原来的parent视为cur。如下:
在这里插入图片描述
然后按照情况2.1的方式处理,即对grandpa进行右旋,然后将parent变成黑色,grandpa变成红色

情况2.4: cur 是parent 的左边,并且parent是grandpa的右边
解决方式与2.3类似:对parent右旋,在对grandpa左旋

AVL树和红黑树的比较

红黑树和AVL树都是高效的平衡二叉树,增删改查的时间复杂度都是O(log(n)),红黑树不追求绝对平衡,其只需保证最长路径不超过最短路径的2倍,相对而言,降低了插入和旋转的次数,所以在经常进行增删的结构中性能比AVL树更优,而且红黑树实现比较简单,所以实际运用中红黑树更多

红黑树的应用

  1. java集合框架中的:TreeMap、TreeSet底层使用的就是红黑树
  2. C++ STL库 – map/set、mutil_map/mutil_set
  3. linux内核:进程调度中使用红黑树管理进程控制块,epoll在内核中实现时使用红黑树管理事件块
  4. 其他一些库:比如nginx中用红黑树管理timer等
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

运笔如飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值