红黑树

https://www.cnblogs.com/hello-shf/p/11364565.html#_lab2_2_1

二三树

1、 2节点有且只能有两个孩子节点,并只能包含一个数据项。
2、 3节点必有三个孩子,并只能包含两个数据项,从左至右依次递增
3、 插入节点时不能将该节点插入到一个空节点上,新的节点只能通过分裂或者融合产生
4、 当2-3树只有2节点的时候,其只能是一棵满二叉树(完美二叉树)
在这里插入图片描述

https://blog.csdn.net/qq_36610462/article/details/83277524

二叉查找树(BST)

1.左子树上所有结点的值均小于或等于它的根结点的值。

2.右子树上所有结点的值均大于或等于它的根结点的值。

3.左、右子树也分别为二叉排序树。

img

红黑树

1.节点是红色或黑色。

2.根节点是黑色。

3.每个叶子节点都是黑色的空节点(NIL节点)。

4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)

5.从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点

特点:

  1. 红黑树黑节点自平衡
  2. 从根到叶子的最长路径不会超过最短路径的2倍

img

变色:

为了重新符合红黑树的规则,尝试把红色节点变为黑色,或者把黑色节点变为红色。

左旋转:

逆时针旋转红黑树的两个节点,使得父节点被自己的右孩子取代,而自己成为自己的左孩子。图中,身为右孩子的Y取代了X的位置,而X变成了自己的左孩子。

img

右旋转:

顺时针旋转红黑树的两个节点,使得父节点被自己的左孩子取代,而自己成为自己的右孩子。图中,身为左孩子的Y取代了X的位置,而X变成了自己的右孩子。

img

案例

如果在22后面加一个21。 需要将25、22、27都变色,且21为红色。

img

此时节点17和节点25是连续的两个红色节点,

把节点17变成黑色节点:一来不但打破了规则4,二来根据规则2(根节点是黑色),也不可能把节点13变成红色节点。

把节点13看做X,把节点17看做Y。进行左旋转。

img

由于根节点必须是黑色节点,所以需要变色,变色结果如下:

img

此时其中两条路径(17 -> 8 -> 6 -> NIL)的黑色节点个数是4,其他路径的黑色节点个数是3,不符合规则5。

把节点13看做X,节点8看做Y,像刚才的示意图那样进行右旋转:

img

最后根据规则来进行变色:

img

红黑树重新符合规则。这一个例子的调整过程比较复杂,经历了如下步骤:

变色 -> 左旋转 -> 变色 -> 右旋转 -> 变色

ref:
30张图带你彻底理解红黑树:https://www.jianshu.com/p/e136ec79235c
AVL-平衡二叉树的原理和实现:https://www.cnblogs.com/hello-shf/p/11352071.html#_label3
通过2-3树理解红黑树:https://www.cnblogs.com/hello-shf/p/11364565.html#_lab2_2_1
红黑树复杂度的数学证明:https://blog.csdn.net/u013742253/article/details/20777761?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control
二叉平衡搜索树、红黑树、二三树:https://blog.csdn.net/u013073869/article/details/107423756

查找操作

  1. 从根结点开始查找,把根结点设置为当前结点;
  2. 若当前结点为空,返回null;
  3. 若当前结点不为空,用当前结点的key跟查找key作比较;
  4. 若当前结点key等于查找key,那么该key就是查找目标,返回当前结点;
  5. 若当前结点key大于查找key,把当前结点的左子结点设置为当前结点,重复步骤2;
  6. 若当前结点key小于查找key,把当前结点的右子结点设置为当前结点,重复步骤2;
    正由于红黑树总保持黑色完美平衡,所以它的查找最坏时间复杂度为O(2lgN),也即整颗树刚好红黑相隔的时候。

时间复杂度
二叉排序树:O(Log2n)到O(n)之间

  • n个节点的二叉排序树的高度为Log2n+1,其查找效率为O(Log2n),近似于折半查找。
  • 二叉排序树完全不平衡,则其深度可达到n,查找效率为O(n),退化为顺序查找。
    平衡二叉搜索树:
  • O(logn)
    红黑树:O(logn)、 n为数据个数。
  • 查找最坏时间复杂度为O(2lgN),也即整颗树刚好红黑相隔的时候。
  • 红黑树会比普通的平衡二叉树(AVL树)搜索效率要低一些。

插入操作

查找插入位置:

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

插入节点为红色:

  • 插入结点是红色,若父结点(如果存在)为黑色结点时,红黑树的黑色平衡没被破坏,不需要做自平衡操作。
  • 插入结点是黑色,那么插入位置所在的子树黑色结点总是多1,必须做自平衡。

插入情景

  1. 红黑树为空树:直接把插入节点作为根节点。
  2. 插入节点key已存在:把插入节点设置为将要替代节点的颜色,并把当前节点值更新为插入节点值。
  3. 插入节点父节点为黑节点:直接插入。
  4. 插入节点父节点为红节点:
    特点:插入结点总是存在黑色的祖父结点。
    依据:根结点是黑色,不可以同时存在两个相连的红结点
    推导:如果插入的父结点为红结点,那么该父结点不可能为根结点。
    1
    4.1:叔叔结点存在并且为红结点
    操作:
  • 将P和S设置为黑色
  • 将PP设置为红色
  • 把PP设置为当前插入结点
    三种情况:
  • 如果pp节点的父节点是黑色,无需操作。
  • 如果pp节点的父节点是红色,把pp节点当作新插入的节点,继续做自平衡操作。
  • 如果pp节点是根节点,重新把pp节点设置为黑色。(此时,红黑树的黑色节点层数增加了,这是唯一一种情况)
    总结:
  • 红黑树的生长是自底向上的。普通二叉查找树的生长是自顶向下的。
  • 每棵子树都能自平衡,那么整棵树最终总是平衡的。

4.2:叔叔节点不存在或为黑色,并且插入结点的父亲结点是祖父结点的左子结点
旋转操作:子树一边的节点多了,需要租借给另一边。左多右旋,右多左旋
4-2-1
4.2.1:插入结点是其父结点的左子结点

  • 对pp右旋。
  • 将p设为黑色
  • 将pp设为红色
    补充:也可以把p设为红色,i和pp设为黑色。可以,但是此时需要考虑p节点的父节点是不是红色。自己能消化的就不要麻烦祖辈了。
    4.2.2:插入结点是其父结点的右子结点
  • 对p左旋。
  • 将p设为插入节点
  • 重复4.2.1

4.3:叔叔结点不存在或为黑色,并且插入结点的父亲结点是祖父结点的右子结点
4.3.1:插入结点是其父结点的右子结点

  • 对pp左旋
  • 将p设为黑色
  • 将pp设为红色
    4.3.2:插入结点是其父结点的左子结点
  • 对p右旋
  • 将p设为插入节点
  • 重复4.3.1

1

删除操作

查找目标结点,不存在目标结点时,忽略本次操作;当存在目标结点时,删除后需要找结点来替代删除结点的位置,做自平衡处理。

三种情况:
情景1:若删除结点无子结点,直接删除
情景2:若删除结点只有一个子结点,用子结点替换删除结点
情景3:若删除结点有两个子结点,用后继结点(大于删除结点的最小结点)替换删除结点

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值