码迷,mamicode.com
首页 > 其他好文 > 详细

5分钟学会红黑树插( insertint elements into a red black tree)

时间:2018-09-01 21:54:17      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:不能   线性   旋转   额外   http   严格   nts   技术   集合框架   

前言:本文解决的问题

  • 什么是红黑树
  • 什么时候使用红黑树
  • 红黑树插入元素时如何保持平衡

1 什么是红黑树

红黑树(Black red Tree) 是一棵自平衡树,每个节点都遵循以下四条:

  • 所有节点只能是红色或者黑丝
  • 根节点是黑色
  • 只存在相邻的红色节点(即红色节点不能有红色的父节点或者红色的孩子)
  • 任意从root到Nil节点,经过的路径中黑色节点的数目是一样的。

具体可以见下图
技术分享图片

2 什么时候用红黑树

2.1 为什么会提出红黑树

我们知道,一般在平衡二叉树(BST)作插入、删除、更新、查找的时间复杂度是O(log n),但是对于那种变形的BST(往一边偏的,变成线性的)时间复杂度就会变成O(n)。红黑树提供了为插入删除提供了最坏的时间保证2O(log n) ,因为它可以保持自平衡,总能把高度维持在 2log(n+1) (n为节点数目)。

2.1 什么时候用红黑树

相比AVL树而言,红黑树没有严格定义左右子树高度差值,并不严格意义的平衡。如果要涉及到很多插入、删除,用AVL的话会很多次旋转(rotation),此时红黑树是更好的选择。反之,查询多,更改少,即静态的话AVL是更好的选择。在查询效率上,由于AVL树严格平衡,AVL树会比红黑树略快,但时间复杂度是要给数量级上的。此外,相比较AVL树而言,红黑树需要额外的O(n)的空间来存储颜色。

在java集合框架中TreeSet和TreeMap是用红黑树实现的。


3 红黑树的插入

3.1 插入情况分类

放方便后续说明,假设要插入的节点为Z,插入后Z的父节点为,Z.parent;Z父节点的兄弟为Z.uncle

  • Case 1插入后Z本身就是根元素
    技术分享图片
    如上图所示,插入后就只有这个一个元素,此时直接把该节点变为黑色即可。

  • Case 2 插入后Z的父节点是黑色(Z.parent = black )
    技术分享图片
    这种完全符合红黑树的特性,不需要做出更改

  • Case 3 Z的父节点和叔叔节点都是红色(Z.uncle and parent = red/recolor)
    这种违反了红黑树的第三代你特征,即不存在父子节点都是红色的,只需要把父节点和叔叔节点都变成黑色(Z.parent = black; Z.uncle = black),同时上面根节点颜色变成红色。

  • Case 4 .Z的父节点是红色,叔叔节点是黑色,Z与父节点和祖父节之间是RL或者LR的情况。(即Z.parent = black and uncle = black(triangle) ->rotate.Z.parent)
    和第三种一样违反了父子节点都是红色的特性。此时需要作的是把RL或者LR旋转变成LL或者RR情况的,具体做法就说旋转Z.parent.

  • Case 5 Z的父节点红色,叔叔节点是黑色的,Z与父节点、祖父节点在一条线上,即LL和RR的情况。(Z.uncle = black(line)->rotate.Z.grandparent &&recolor)
    旋转Z的祖父节点,并重新着色,使满足红黑树特性。
    技术分享图片

    3.2 实际举例(针对case3、case4和case5分别举例)



    下图中10是要加入的节点,初始树如下
    技术分享图片

    case 3,父亲和叔叔节点都是红色的

    把10加在末尾,涂红色
    技术分享图片
    把Z.parent 变成黑色,Z.uncle变成黑色,为维持从上往下的路径中黑色节点数量不变,需要把Z.grandparent=red


    技术分享图片

    case 3,叔叔节点黑色,而且是三角形的,如图

    技术分享图片


    把Z.parent旋转
    技术分享图片


    结果如下
    技术分享图片

    case 5,叔叔节点黑色,而且是线性的,如图

    技术分享图片


    旋转Z的祖父节点,rotate the Z.grandparent,如图:
    技术分享图片


    把旋转后的重新着色

技术分享图片

4总结

红黑树的插入元素,总的来说分两部,先旋转,再着色。旋转把RL和LR型变成RR或者LL型,然后再旋转上一级元素;着色要满足红黑树的特性

参考文献

https://en.wikipedia.org/wiki/Red%E2%80%93black_tree

5分钟学会红黑树插( insertint elements into a red black tree)

标签:不能   线性   旋转   额外   http   严格   nts   技术   集合框架   

原文地址:https://www.cnblogs.com/java-learner/p/9571194.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!