红黑树.jpg

前言

在学习了几天的红黑树相关知识后,把自己的所学所想写出来供大家一起讨论下。红黑树是一种比较难的数据结构,书上,还有一些视频中的讲法越看越不明白,第一遍看懂了,下次在看就又不懂了,尤其是在插入后的旋转和变色,如果你在学习中遇到疑问,那么本文对你会有点帮助。

目录

红黑树的定义

红黑树是一种特殊的二叉查找树,含有红黑节点并能自平衡,其时间复杂度为O(logn)。

红黑树的性质

  1. 每个结点不是红色就是黑色
  2. 不可能有连在一起的红色结点
  3. 根结点都是黑色root
  4. 每个红色结点的两个子结点都是黑色,叶子结点都是黑色

祖父节点.png

上图就是一个简单的红黑树,并且将红黑树一些节点的叫法标了出来,便于后面的讲解。

红黑树的左旋、右旋和变色

左旋:将要旋转的结点往左边下移,其右节点上移,右结点的左子树连接在旋转节点的右边
左旋.png
右旋:将要旋转的结点往右边下移,其左结点上移,左结点的右子树连接在旋转节点的左边
右旋.png
变色:结点的颜色由红变黑或由黑变红。

旋转操作是局部的。当一边子树的结点少了,那么向另外一边子树“借”一些结点;当一边子树的结点多了,那么向另外一边子树“租”一些结点。红黑树总能通过旋转和变色达到自平衡。

红黑树的查找

由于红黑树底层结构是二叉查找树,所以其跟二叉查找树的查找一样。

  1. 从根结点开始查找,把根结点设置为当前结点;

2. 若当前结点为空,返回null;
3. 若当前结点不为空,用当前结点的key跟查找key作比较;
4. 若当前结点key等于查找key,那么该key就是查找目标,返回当前结点;
5. 若当前结点key大于查找key,把当前结点的左子结点设置为当前结点,重复步骤2;
6. 若当前结点key小于查找key,把当前结点的右子结点设置为当前结点,重复步骤2;

红黑树的插入

包含两部分,一是查找插入的位置,二是插入后自平衡,查找插入的父节点和查找操作区别不大。

查找插入

  • 从根结点开始查找;
  • 若根结点为空,那么插入结点作为根结点,结束。
  • 若根结点不为空,那么把根结点作为当前结点;
  • 若当前结点为null,返回当前结点的父结点,结束。
  • 若当前结点key等于查找key,那么该key所在结点就是插入结点,更新结点的值,结束。
  • 若当前结点key大于查找key,把当前结点的左子结点设置为当前结点,重复步骤4;
  • 若当前结点key小于查找key,把当前结点的右子结点设置为当前结点,重复步骤4;

插入的位置找到了,把插入节点放在正确的位置就好了,插入的节点要是红色,这是因为,红色不会破坏红黑树的黑色平衡,要是插入节点为黑色,那么插入位置所在的子树黑色节点总是多1,就必须要做自平衡。

接下来就是插入后的旋转和颜色的变换规则,这一部分网上都是分了很多情况进行分析,我学习后进行总结,总结了多条,只要记住就好了,适用于所有情景。

插入后旋转和颜色变换规则:所有插入的点默认为红色

  1. 变颜色的情况:当前结点的父亲是红色,且它的祖父结点 的另一个子结点也是红色(叔叔结点)

    • 把父结点设为黑色
    • 把叔叔结点也设为黑色
    • 把祖父也就是父亲的父亲设为红色(爷爷)
    • 把指针定义到祖父结点设为当前要操作的点(爷爷)进行分析变换规则
  2. 左旋:当前父结点是红色,叔叔是黑色的时候,且当前的结点是右子树。左旋以父结点作为左旋。
  3. 右旋:当前父结点是红色,叔叔是黑色的时候,且当前的结点是左子树。右旋

    • 把父结点变为黑色
    • 把祖父结点变为红色(爷爷)
    • 以祖父结点旋转(爷爷)

红黑树右旋.png
这个规则适用于插入节点后全部的情景,可以对照图进行分析,只要把个规则记住,那么红黑树的插入自平衡就能掌握了。

红黑树的插入这么一看的就不是很复杂,还有红黑树的删除,但是红黑树的删除我并没有想到总结出来几条规则,是需要进行情景分析的,这部分网上都有很多前辈进行分析了,那删除这一块我就先不写了,等我想到比较容易理解的,我在来更新。

结语

目前只写到这一部分,最大头删除这一部分想到较容易的在更新,或者等在加深理解的时候在来分享,希望这篇文章能帮助到大家,看完这篇要是对插入还有疑问,可以将疑问在评论区写出来,我会尽量解答,当然如果有前辈有不同的看法,也可以写出来,大家一起讨论,谢谢!


zvkk
1 声望1 粉丝

计算机视觉玩家


引用和评论

0 条评论