python 红黑树的基础

#这个可以自己画画图
https://www.cs.usfca.edu/~galles/visualization/RedBlack.html

在这里插入图片描述

在这里插入图片描述
NII是虚拟出来的

找到圆心(一定是子节点)和旋转的节点

p绕c节点

只要旋转,子树资源互换了,祖父母都降级了,要不给点好处,所有把原来的子树抢过来,给父母了

左旋转
在这里插入图片描述

右选转
在这里插入图片描述
在这里插入图片描述

叔叔没有子节点,就是nil 也是null

在这里插入图片描述

红黑树插入所有的情况
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

红黑树具有如下性质:

  1. 红黑树是一颗平衡二叉树搜索树,其中序遍历单调不减
  2. 节点是红色或黑色
  3. 根节点是黑色
  4. 每个叶节点(也有称外部节点的,目的是将红黑树变为真二叉树,即NIL节点,空节点)是黑色的
  5. 每个红色节点的两个子节点都是黑色。(换句话说,从每个叶子到根的所有路径上不能右两个连续的红色节点)
  6. 从根节点到每个叶子的所有路径都包含相同数目的黑色节点(这个数值叫做黑高度)我们在任何一个分支上去找的时候黑色节点的个数要是相同的

经过上面的定义,我们可以发现下面几个事实:

  1. 两个红节点不能相连接
  2. 从x到x的后代叶子节点的路径上,黑色节点的数量是相同的。我们可以把这个数量定义称为bh(x).其中不包含x
  3. 从根节点到叶节点的长度差不会超过一倍
  4. 包含n个内部节点的红黑树,height <= 2long(n+1)

在这里插入图片描述

回顾下 左旋和右选
在这里插入图片描述

在这里插入图片描述

情况1: 插入的是根节点
原树是空树,此情况只会违反性质2
对策: 直接把此节点涂为黑色

情况2: 插入的节点的父节点是黑色
此不会违反性质2和性质4,红黑树没有被破坏
对策: 什么也不做

情况3: 插入当前节点是4,它的父节点是红色且父亲的兄弟节点(叔叔节点)是红色

在这里插入图片描述

对策将当前节点的父节点和叔叔节点涂黑,爷爷节点涂红(就是7),把当前节点(2)指向爷爷节点,从新的当前节点重新开始算法

在这里插入图片描述

情况4:当前节点(目前就是7)的父节点是红色,叔叔节点是黑色(父亲的兄弟节点),当前节点(目前是7)是其父节点的右子

对策 当前节点(目前是7)的父节点做为新的当前节点,当前节点是其父节点的右子
对策:当前节点的父节点做为新的当前节点,以新当前节点为支点左旋
在这里插入图片描述
情况5: 当前节点(目前是2了)的父节点是红色,叔叔节点是黑色(父节点的兄弟是14),当前节点是其父节点的左子

对策当前节点(目前是2)的父节点做为新的当前节点,以新当前节点为支点右选。颜色也要改变

变化后
在这里插入图片描述

在一次详细解说下

插入:
将需要插入的元素z按照常规的二叉搜索树进行插入,颜色是红色
然后需要处理对于红黑树的定义违反之处
根节点是红色的,那么就让根节点变成黑色
z和z的父节点都是红色的,处理这种情况,总共有三种

六种冲突情况的处理,假设新加入的节点是z:
一、. 父节点和父节点的兄弟节点都是红色的处理方法

  • 将插入z的父节点和父的兄弟节点都变成黑色
  • 将z的祖父节点变成红色
  • z的祖父节点变成红色后,循环处理冲突

在这里插入图片描述

二、 当我们插入的z节点,z的父节点是红色,父亲的兄弟节点是黑色,z的父节点是左孩子,z是右孩子 —这样是左移

  1. 在z的父节点执行左移动操作
  2. 让z的左孩子称为新的新插入的z节点,继续处理冲突

在这里插入图片描述
上图返过来

z的父节点是红色,z父亲节点兄弟是黑色,z的父节点是右孩子,z是左孩子 --这样是右移

  1. 在z的父亲节点执行右移操作
  2. 让z的右孩子称为新的新插入的z节点,继续处理冲突

三、z的父节点是红色,z的父节点兄弟是黑色,z的父节点是左孩子,z是左孩子

  1. 在z的祖父节点右移一次
  2. 将z的parent和z的兄弟节点交换颜色

在这里插入图片描述

在这里插入图片描述

z的父节点是红色,z的父节点的兄弟是黑色,z的父节点是右孩子,z是右孩子

  1. 在z的祖父节点左移一次
  2. 将z的parent和z的兄弟节点交换颜色

查找:

  • 就是按照二叉搜索树的查找,不必阐述

删除:

  • 先回顾二叉搜索树的删除操作
  1. 如果删除的节点是z,z没有孩子节点,直接删
  2. 如果z包含有一个孩子,那么就将z去除掉,让z的这个孩子替代之前z的位置
  3. 如果z包含两个孩子,我们就去寻找一successory来代替z,然后将y删除,又是一个递归的过程

sucessory的寻找顺序
z右孩子的最左节点
z左孩子的最右节点

举个例子(删除节点中的32)
比44要小,比17要大

在这里插入图片描述
发现32右子树是空,如果右子树不为空,就要找左子树,最右边,32的右子树的最左边
在这里插入图片描述
删除65
要不就找右子树的左节点,递归去找,要不就找左子树右节点递归找
在这里插入图片描述

红黑树的删除操作:

  1. 就像是普通的搜索二叉树一样删除一个节点z

  2. 如果z包含右两个孩子,那么拷贝y的值给z的时候,不要复制颜色

  3. 让y成为需要被删除的那个节点

  4. 如果y是红色,那么不影响红黑树的属性

  5. 如果y是黑色的,那么就一定生产了红黑树的冲突

  6. 假设x是y的那个唯一的孩子节点,x也有可能为空

    • 假设x是红色的,直接将x改成黑色即可
    • 假设x是黑色的
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

伟伟哦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值