数据结构-红黑树

红黑树

红黑树的五大特性:

  1. 根节点是【黑色】
  2. 【红色】节点的子节点一定都是【黑色】,但是黑色节点的子节点可以是红色和黑色
  3. 每个叶子节点都是黑色的空节点(NIL),因为叶子节点不存储数据
  4. 任意一个节点到叶子节点的路径上所包含的【黑色】节点的数量是相同的
    这个也称之为【黑色完美平衡】
  5. 新插入的节点必须是【红色】
    为什么?如果新插入的节点是【黑色】,那不管是在插入到那里,一定会破坏黑色完美平衡的

根据以上性质可以推断出:所以红黑树左右子树高度差最大为2倍
——左边n个黑色节点,右边n个黑色节点,然后两个黑色节点中间插入一个红色节点。所以右边n黑色+n红色

为什么红黑树被广泛应用?

二叉搜索树bst极端情况下时间复杂度退化为O(n)

平衡二叉树AVL 虽然效率非常高,但是每次插入、删除都要做调整,所以对于有频繁的插入、删除操作的数据集合,使用 AVL 树的代价就有点高了。

红黑树即不像二叉查找树那样存在复杂度退化的问题,
也不会像完成平衡二叉树那样为了保证完全的平衡而过多的旋转调整。
算是在查找和增删之间取了很好的平衡。
红黑树的高度近似 log2n,增删改查操作的时间复杂度都是 O(logn)

应用场景:

  • java的hashmap、 TreeMap 、TreeSet 底层用到红黑树

  • c++ stl中的map、set底层就是红黑树

  • epoll在内核中的实现,用红黑树管理文件描述符fd

插入过程的旋转变色

详细图文

1、当前节点为空,直接插入即可
2、插入的节点已经存在,直接替换即可
3、插入节点的父节点为【黑色节点】,找到父节点,直接插入即可。因为这个树本来就是黑色完美平衡了,再新插入一个新的红色节点,并不会破坏树的平衡以及红黑树的特性。

4、插入节点的父节点为红色
现在,插入的节点的父节点为红色节点,而红色节点一定不可能为根节点,所以可以推断出新插入节点的父节点一定还有父节点
在这里插入图片描述
那现在很显然违反了上面的特性 3( 每个【红色】节点的两个子节点一定都是【黑色】),而现在是两个红色节点相连了,这个该怎么处理?此时又继续拆分不同的情况了

第 4-1 种情况:插入节点的叔叔节点存在,且为红色
这个时候你看的树大致是这样子的结构
在这里插入图片描述
解决办法:① 将 P 和 U 变成黑色;② 将 PP 变成 红色
如下图:
在这里插入图片描述
第 4-2 种情况:叔叔节点不存在,且插入节点的【父节点】是插入节点爷爷节点的【左子节点】
在这里插入图片描述

  • 第 4-2-1 种情况:
    插入节点为其父节点的左子节点,也即 LL 双红色的情况(第一个 L 表示插入节点的父节点,第二个 L 表示插入节点)
    这种情况的完整的变换流程如下:

在这里插入图片描述

  • 第 4-2-2 种情况:
    插入节点为其父节点的右子节点,也即 LR 双红色的情况
    其完成的变换流程如下:
    在这里插入图片描述
    第 4-3 种情况:叔叔节点不存在,且插入节点的【父节点】是插入节点爷爷节点的【右子节点】
    在这里插入图片描述
    这种情况依旧是继续区分插入节点是其父节点的左子节点还是右子节点

  • 第 4-3-1 种情况:
    插入节点为其父节点的右子节点,也即 RR 双红色的情况(第一个 R 是插入节点的父节点,第二个 R 是插入节点)
    其整个转换流程是这样的
    在这里插入图片描述

  • 第 4-3-2 种情况:
    插入节点为其父节点的左子节点,也即 RL 双红色的情况
    其完整的转换流程是这样子的:
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值