nginx数据结构之红黑树(2)

1 红黑树简介

红黑树是一种自平衡的二叉查找树,不同于AVL树,它并不是绝对平衡的,它是在一定规则下维持的平衡。

红黑树的规则:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色的。
(3)每个叶子结点为黑色(这里叶子结点指的是空结点,个人认为在操作红黑树时,可以忽略该条规则)。
(4)红色结点的孩子结点必须是黑色的,即两个红色结点不能相邻.
(5)从一个结点开始到达每个叶子结点的路径黑色结点的数目都是相同的,又可将红黑树的平衡看为黑色平衡

2 红黑树的操作

1)插入

找到待插入的位置,将新插入的结点的颜色设为红色,插入后检查树是否符合规则,若不符合规则,需要进行旋转和重新上色的操作。
1)被插入的节点是根节点,直接把此节点涂为黑色(规则2)。
2)被插入的节点的父节点是黑色,无需操作,自然平衡。
3)被插入的节点的父节点是红色,违反了规则4,需根据叔叔结点(父节点的兄弟结点,即祖父结点的另一个子节点)的颜色与位置进行调整,根本思想就是将破坏规则的红色结点不断上移调整到根节点,再将其设置为黑色,上移可通过逐层上移或旋转上移。可按照下述三种情况调整:

叔叔结点为红色修改父节点与叔叔结点的颜色为黑色,将祖父结点的颜色设为红色并使其成为当前结点
叔叔结点为黑色,当前结点为其父节点的右孩子以父节点作为当前结点,并进行左旋操作
叔叔结点为黑色,当前结点为其父节点的左孩子父节点设为黑色,祖父结点设为红色,对祖父结点进行右旋

叔叔结点为黑色的后两种情况,可以结合AVL树的二次旋转平衡进行理解,只不过是在旋转的基础上加上了变色的操作

以下面图片为例,具体说明一下调整方法:
在这里插入图片描述
7 为待插入结点,将其设置为红色,其父节点8,叔叔结点18均为红色,需要将8、18调整为黑色,将祖父结点15调整为红色,此时将15作为当前待调整结点。15的父节点5为红色,叔叔结点30为黑色,根据规则找到15的祖父结点19,失衡类型为左右型,因此需要对结点19进行左右旋二次旋转,即先对19的子节点5进行左旋(即将红色结点15进行了上移操作),将5的父节点15进行变色处理,随后再将5的祖父结点19变为红色再进行右旋。

2)删除

红黑树的删除操作先按照二叉查找树的方法进行删除,删除后,若红黑树没有保持平衡,再通过旋转与重新上色的方法修正该树。

3 为什么要有红黑树

红黑树与AVL树的算法时间复杂度形同均为O(logn),可实现的功能均相同,那么为什么要有红黑树,以及那种情况下需要使用到红黑树?

1)相较于AVL树的优势

红黑树放弃了绝对平衡,只要求再一定规则下达到平衡,即再插入或删除时,为保证平衡的旋转次数降低了(任何不平衡都会在三次旋转之内解决),相较于AVL树,插入与删除的性能得到了提升,但查找的性能逊色于AVL树,,因为红黑树比AVL树不平衡约为n层,n为黑色结点的个数,即AVL树的最大深度为O(logn)层,而红黑树为2O(logn)层,查找数据时比较次数最多差一倍,再对查询性能要求不严格,担忧频繁进行插入/删除的场景下,应使用红黑树。二者的算法时间复杂度相同,均为O(logn).

2)相较于哈希表,红黑树的使用场景

1、hash查找的时间复杂度为O(1),插入与删除的时间复杂度为O(n);而RB树的查找速度是log(n),但hash还要考虑构造表时的耗时。
2、哈希表是一种利用空间换取时间的方式,若对内存要求严格,不适合采用hash。
3、红黑树是有序的,Hash是无序的,需根据需求来选择。
4、在动态场景,如需要扩展时,可选用红黑树。在静态场景下,使用哈希表性能会更好些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值