红黑树-“旋转”实现自平衡概念理解(动图演示)

红黑树-“旋转”实现自平衡概念理解(动图演示)

红黑树(Red-Black Tree),又称“R-B树”,属于“二叉查找树”的一种,但它比较特殊,能够实现树结点的“自平衡”特性,但这种平衡只是近似的,不是绝对平衡。而这一特性使得红黑树能够保证在最坏情况下,基本动态集合的操作时间复杂度为O(lgn)。树中每个结点包含5个属性:key、color、left、right 和 p。

根据《算法导论》中,红黑树的描述定义为:

  1. 每个结点或是红色的,或是黑色的;
  2. 根结点是黑色的;
  3. 每个叶结点(NIL / NULL)是黑色的;
  4. 如果一个结点是红色的,则它的两个子结点都是黑色的;
  5. 对每个结点,从该结点到其后代叶结点的简单路径上,均包含相同数目的黑色结点。(概念:根据性质5,所得到的黑色结点数,又称为“黑高(black-height)",记作 bh(x),注意不包含当前结点,“NIL / NULL”的黑高为0)。

以该图的红黑树为例,将“H”结点视为当前结点,而此时的从“H”结点开始的路径1、2、3中所包含的黑色结点数目一致,任意结点都符合性质5。
在这里插入图片描述

红黑树主要通过“旋转” + 红黑色约束来实现“自平衡”,首先阅读一下来自《算法导论》中关于“左旋”的伪代码描述,理解后“右旋”的原理也大致大致:

LEFT-ROTATE的伪代码中,假设x.right != T.nil,且根结点的父结点为T.nil

y = x.right	//set y
x.right = y.left	//turn y's left subtree into x's right subtree
if y.left != T.nil
	y.left.p = x
y.p = x.p	//link x's parent to y

if x.p == T.nil
	T.root = y
else if x == x.p.left
	x.p.left = y
else x.p.right = y

y.left = x
x.p = y
		

“左旋演示”
在以下红黑树插入新结点“0008”为例,演示整个“左旋”的过程细节:
在这里插入图片描述

上述“左旋”的详细执行步骤:

  1. 插入“0008”结点;
  2. 0008 >= 0002,看右子树;
  3. 0008 >= 0004, 看右子树;
  4. 0008 >= 0006, 看右子树;
  5. 0008 >= 0007, 看右子树;
  6. 发现空树或叶子结点,插入元素;
  7. 当前结点为0008,结点0008和父结点0007都是红色,叔叔结点0005也是红色(从当前结点0008的祖父结点0006推算得到),于是将叔叔结点0005和父结点0007的颜色改为黑色,而祖父结点改为红色;
  8. 当前结点为0006,结点0006和父结点0004都是红色,当前结点是右子结点,父结点是右子结点,需要进行旋转;
  9. 进行左旋,结点0004成为根节点且由红变黑色,结点0002变成结点0004的左子树结点且由黑变红色,而结点0004的原左子树结点0003成为结点0002的右子树结点;
  10. 左旋完成,实现了二叉树自平衡。

“右旋”演示
在以下红黑树插入新结点“0001”为例,演示整个“右旋”的过程细节:

在这里插入图片描述

上述“右旋”的详细执行步骤:

  1. 插入新结点“0001”;
  2. 0001 < 0007,看左子树;
  3. 0001 < 0005,看左子树;
  4. 0001 < 0003,看左子树;
  5. 0001 < 0002,看左子树;
  6. 发现空树或叶子结点,插入元素;
  7. 当前结点0001和父结点0002都是红色,叔叔结点0004也是红色(从当前结点0001的祖父结点0003推算得到),于是将叔叔结点0004和父结点0002的颜色改为黑色,而祖父结点0003改为红色;
  8. 当前结点0003和父结点0005都是红色的,当前结点0003是左子结点,父结点0005是左子结点,需要进行旋转;
  9. 进行右旋,结点0005成为根节点且由红变黑色,结点0007变成结点0005的右子树结点且由黑变红色,而结点0005的原左子树结点0006成为结点0007的左子树结点;
  10. 右旋完成,实现了二叉树自平衡。

说明:红黑树的概念远不止上述的内容,有兴趣的小伙伴可以自行深入学习,本文主要是为了辅助理解“旋转”这一抽象过程。

参考自:
《算法导论》

动图在线演示网址:https://www.cs.usfca.edu/~galles/visualization/RedBlack.html

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值