数据结构---------红黑树

目录

为什么要使用红黑树?

AVL与红黑树

什么是红黑树?

红黑树的平衡性

红黑树的调整

变色

旋转

左旋转

右旋转

变色或旋转的案例


为什么要使用红黑树?

二叉排序树BST在进行查找、最大值、最小值、插入等操作时,期望的时间复杂度是 O(logn) 。但是BST在极端情况下会出现斜树(退化成一条链表),BST的时间复杂度将会变成O(n)。为了保证BST的所有操作的时间复杂度为O(logn),就要想办法把一颗BST树的高度一直维持在logn。红黑树通过变色和旋转等操作,高度始终都维持在logn,从而确保查找、插入等操作的时间复杂度。

AVL与红黑树

AVL 树比红黑树更加平衡,但AVL树在插入和删除的时候会存在大量的旋转操作,影响效率。所以,当程序需要频繁的插入和删除操作,应该选择性能更好的红黑树;当然,如果程序中涉及的插入和删除操作并不频繁,而是查找操作相对更频繁,那么就优先选择 AVL 树进行实现。

什么是红黑树?

红黑树是一种自平衡的二叉查找树,它通过下列规则,保持二叉树的平衡性。

  • 任何一个结点都有颜色,黑色或者红色;
  • 根结点是黑色的;
  • 父子结点之间不能出现两个连续的红色结点(每个红色节点的两个子节点都是黑色);
  • 任何一个结点向下遍历到叶子结点,所经过的黑结点个数必须相等(相同的黑色高度);
  • 每个叶子结点都是黑色的空结点(NIL 结点);

这就是一棵典型的红黑树,分析如下:

树中的每个结点的颜色要么是黑色,要么是红色;

根结点 13 为黑色结点;

树中不存在两个相邻的红色结点,比如:结点 17 为红色结点,其父亲节点 13 与两个孩子结点15和25就一定是黑色,而不能是红色;

从结点到其后代的 NIL 结点 的每条路径上具有相同数目的黑色结点,比如:根结点 13 到其左子树的 NIL 结点 包含三个黑色结点,到其右子树所有的 NIL 结点也包含三个黑色结点。

红黑树结点类参考实现:

java 复制代码
class  Node<T>{
   public  T value;
   public   Node<T> parent;
   public   boolean isRed;
   public   Node<T> left;
   public   Node<T> right;
}

红黑树的平衡性

向红黑树插入值为14的新结点,由于父结点15是黑色结点,因此这种情况并不会破坏红黑树的规则,无需做任何调整。

向红黑树插入值为21的新节点,由于父节点22是红色节点,因此这种情况打破了红黑树的规则3(每个红色节点的两个子节点都是黑色),必须进行调整,使之重新符合红黑树的规则。

红黑树的调整

当红黑树在添加元素后,平衡性被破坏时,就需要进行调整,来保持符合红黑树的规则。调整的方法有两种:变色旋转。旋转又分为两种形式:左旋转和右旋转。

添加的新元素默认为红色,因为如果插入节点是黑色,就一定会违背每条查找线上黑色节点个数一致的规则,插入红色,就可能不需要变色或者旋转,所以新插入的节点颜色都是红色。

变色

为了重新符合红黑树的规则,尝试把红色节点变为黑色,或者把黑色节点变为红色。

红黑树中的根结点为25的子树中,由于添加新结点21后,导致节点21和节点22连续出现了红色,不符合规则3(每个红色节点的两个子节点都是黑色),所以把节点22从红色变成黑色。

但是,因为的黑色节点22打破了红黑树的规则4(相同的黑色高度),所以发生连锁反应,需要继续把节点25从黑色变成红色。

但是,因为节点25和节点27又形成了两个连续的红色节点,需要继续把节点27从红色变成黑色。

旋转

左旋转

左旋转:逆时针旋转红黑树的两个节点,使得父节点被自己的右孩子取代,而自己成为自己的左孩子。

例如:右孩子Y取代了父节点X的位置,而X变成了自己的左孩子。

右旋转

右旋转:顺时针旋转红黑树的两个节点,使得父节点被自己的左孩子取代,而自己成为自己的右孩子。

例如:左孩子Y取代了X的位置,而X变成了自己的右孩子。

变色或旋转的案例

向红黑树插入值为21的新节点,由于父节点22是红色节点,因此这种情况打破了红黑树的规则3(每个红色节点的两个子节点都是黑色),需要进行调整。

调整第1步:变色

把节点25及其子结点22和27进行变色处理,此时红黑树会出现一个问题:节点17和节点25是连续的两个红色节点,违反了规则3 (每个红色节点的两个子节点都是黑色)。

如果把节点17变成黑色节点,也会出现违反规则4:任何一个结点向下遍历到叶子结点,所经过的黑结点个数必须相等(相同的黑色高度)

调整第2步:左旋转

当变色已无法解决问题时,就需要通过旋转来解决,把节点13看做X,把节点17看做Y,进行左旋转。

调整第3步:变色

由于根节点必须是黑色节点,所以需要变色。

调整第4步:右旋转

由于红黑树中路径(17 -> 8 -> 6 -> NIL)的黑色节点个数是4,其他路径的黑色节点个数是3,违反规则4:任何一个结点向下遍历到叶子结点,所经过的黑结点个数必须相等。

所以需要把节点13看做X,节点8看做Y,进行右旋转

调整第5步:变色

最后根据规则,重新变色。

相关推荐
程序定小飞3 小时前
基于springboot的民宿在线预定平台开发与设计
java·开发语言·spring boot·后端·spring
FREE技术3 小时前
山区农产品售卖系统
java·spring boot
大数据张老师4 小时前
数据结构——折半查找
数据结构·算法·查找·折半查找
星光一影4 小时前
Java医院管理系统HIS源码带小程序和安装教程
java·开发语言·小程序
m0_626535204 小时前
数据结构学习,一些知识点
数据结构·学习
想唱rap4 小时前
C++list类的模拟实现
linux·运维·服务器·数据结构·c++·windows·list
YA3334 小时前
java设计模式七、代理模式
java·设计模式·代理模式
helloworddm5 小时前
Orleans 自定义二进制协议在 TCP 上层实现的完整过程
java·网络协议·tcp/ip
say_fall5 小时前
数据结构之顺序表:一款优秀的顺序存储结构
c语言·数据结构