红黑树理解

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

红黑树的性质

  1. 每个结点不是红色就是黑色

  2. 根节点是黑色的

  3. 如果一个节点是红色的,则它的两个孩子结点是黑色的

  4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点

  5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)

上面的4点性质用自己的话可以总结为:(性质5不用记)

  • 结点不是红色就是黑色

  • 没有连续的红色结点

  • 每条路径上的黑色结点的数量是一样的

AVL树是通过高度来控制平衡的,是严格平衡的。那如果新插入结点很多那么旋转也是要付出代价的。红黑树通过颜色来控制平衡,但不是严格的平衡,它近似平衡。红黑树也可以达到AVL树的效率。它最长路径不超过最短路径的2倍。

那为什么红黑树的最长路径不超过最短路径的2倍呢?

通过上面的性质,假设我们把红黑树的黑色结点单独抽出来,从跟到叶子黑结点个数为N个

那它最短路径就是长度为N
那它最长的路径可能是一黑一红

那它的长度为2N,所以它的最长路径不超过最短路径的2倍,则其他路径的长度就在N-2N之间。那么红黑树增删查改的效率就在logN-2logN之间,和AVL树的logN差不多了。

红黑树的插入

那么我们插入结点时选择插入黑结点还是红结点呢?

当然是选择插入红结点了。选择插入黑结点那麻烦就大了,那1条路径上就多了1个黑结点,破坏了性质4,代价很大。插入红结点,如果它的父亲结点是黑色则不用调整,拍拍屁股走人,它的父亲是红色那我们在进行后序的处理。

总结一下:

  • 插入黑色结点一定破坏性质4,调整起来会很麻烦

  • 插入红结点不一定破坏红黑树的性质,它的父亲结点是红色才进行调整,比插入黑结点调整起来方便。

插入的逻辑:

  • 找到插入结点的位置

  • 插入结点

  • 检测新结点插入后是否破坏了红黑的性质,如果破坏则需要进行处理

因为新插入结点的颜色是红色,若它的父亲结点是黑色不用调整,是红色的话需要对红黑树分情况来讨论。

红黑树调整主要看叔叔结点

下面我们根据叔叔结点的情况来具体看一下。

情况一

以下用p来代表parent结点,c代表cur为新增结点,g代表grandparent结点,u代表uncle结点。
我们还是跟AVL树一样画具象图:

叔叔结点存在且为红

为什么把g变成红色呢?如果g不变成红色,那此时子树上就多了1个黑结点了。
只要我们画出具象图,那面试时手撕红黑树也完全不怂。

当然还有很多种情况,那就给出抽象图:

这种情况下cur在p的左边还是右边都不影响。

情况二

叔叔结点存在且为黑,新增结点是p的左边

这是由情况一变来的,如果u存在那cur一定是黑的,不是新郑结点,这样才满足红黑树的性质。

新增结点是p的右边

情况三

叔叔结点不存在

新增结点在parent的左边

新增结点在parent的右边

总结一下:

以上的情况都是父亲结点在祖先结点的左边,在祖先结点的右边也是相同的处理方法

  • 叔叔结点存在且为红,把父亲结点和叔叔结点变黑,祖先变红继续向上处理直到祖先是根节点

  • 叔叔存在为黑,祖孙三代在一条直线上进行单旋,不在则进行双旋

  • 叔叔不存在,祖孙三代在一条直线上进行单旋,不在则进行双旋

所以2,3的逻辑可以合在一起,分为新增结点在父亲结点的左边还是右边处理。

下面再来简单的说说父亲结点在祖先结点的右边

叔叔存在且为红

此时,cur在p的左边还是右边没有影响。

叔叔存在且为黑

新增结点在父亲结点的右边

新增结点在父亲结点的左边

叔叔不存在

总结一下:

  • 叔叔存在且为红,u,p变黑,g变红继续向上调,直到g为根结点,最后把g变黑

  • 叔叔存在且为黑,祖孙3带在一条直线上单旋,折线要双旋

  • 叔叔不存在,祖孙3带在一条直线上单旋,折线要双旋

红黑树的和AVL树的简单比较

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

         

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
红黑树的删除操作需要进行调整,以保证删除节点后仍然满足红黑树的性质。删除操作涉及到三种情况: 1. 删除节点没有子节点 这种情况比较简单,只需要将待删除节点替换成空节点,并将其颜色设为黑色即可。如果待删除节点是红色节点,那么删除后不会影响红黑树的性质;如果待删除节点是黑色节点,那么删除后会破坏红黑树的性质,需要进行调整。 2. 删除节点只有一个子节点 这种情况需要将待删除节点的子节点替换成待删除节点,并将待删除节点的颜色赋给子节点。如果待删除节点是黑色节点,那么删除后会破坏红黑树的性质,需要进行调整。 3. 删除节点有两个子节点 这种情况比较复杂,需要找到待删除节点的后继节点,将后继节点的值赋给待删除节点,并将后继节点删除。后继节点要么是待删除节点的右子中的最小节点,要么是待删除节点的左子中的最大节点。删除后继节点可能会破坏红黑树的性质,需要进行调整。 下面是红黑树删除的具体调整操作: 1. 如果删除的节点是红色节点,那么删除后不会破坏红黑树的性质,直接删除即可。 2. 如果删除的节点是黑色节点,并且其子节点是红色节点,那么可以将子节点涂黑代替删除节点,并不会破坏红黑树的性质。 3. 如果删除的节点是黑色节点,并且其子节点都是黑色节点,那么需要进行调整。设待删除节点为x,x的兄弟节点为s,x的父节点为p。此时需要分为以下三种情况: (1) x是左子节点,s是右子节点 此时需要进行左旋操作。将p作为新的子根节点,s作为p的左子节点,x的兄弟节点s的右子节点作为s的左子节点。 (2) x是右子节点,s是左子节点 此时需要进行右旋操作。将p作为新的子根节点,s作为p的右子节点,x的兄弟节点s的左子节点作为s的右子节点。 (3) x是左子节点,s是左子节点或者x是右子节点,s是右子节点 此时需要进行重新着色操作。将x的兄弟节点s的颜色涂成红色,将x的父节点p的颜色设为黑色,删除节点x。 最后,需要检查删除节点后红黑树的性质是否仍然满足,如果不满足需要进行相应的调整操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值