面试终结者——“红黑树”实现原理

红黑树(Red Black Tree)是一种自平衡的二叉搜索树,(也叫二叉查找树,该树的结构特点是左子树的键值总小于根节点的键值,右子树的键值总大于根节点的键值),以前也叫平衡二叉 B 树(Symmetric Binary B-Tree)。

预备知识

树的知识结构图,大致如下所示:
在这里插入图片描述

  • 平衡二叉搜索树

平衡二叉搜索树,英文简称BBST,经典常见的有AVL树和红黑树。
1、二叉搜索树,是二叉树的一种,英文简称BST,前文有介绍过。
2、平衡:就是说当节点数量固定时,左右子树的高度越接近,这棵二叉树越平衡(高度越低)。而最理想的平衡就是完全二叉树 / 满二叉树,高度最小的二叉树。
在这里插入图片描述
一颗二叉搜索树平均时间复杂度可以是树得高度O(h)。就像左边这颗,节点的左右子树高度接近描述与一颗平衡二叉树,O(h)= O(logN);而右边这颗,高度达到了最大,已经退化为了链表,O(h)=O(N)。
3、改进二叉树,当二叉树退化为链表时,性能是很低的,所以我们可以在节点的插入、删除操作之后,进行二叉搜索树恢复平衡。

  • AVL树

AVL树是最早发明的自平衡二叉搜索树之一,其中有代表某节点左右子树高度差的平衡因子,每个叶子节点的平衡因子都为 0.看下面这两幅草图
在这里插入图片描述
可以看出它们对应的平衡因子,而右边的这颗AVL树的结构特点很明显,总结如下:
A、每个节点的平衡因子只有可能是0、-1、1这三个值(如果绝对值超过1,则是去平衡)
B、每个节点的左右子树的高度差不超过1
C、搜索、插入、删除的时间复杂度都为O(logN)。

  • B 树

B 树是一中平衡多路搜索树,多用于文件系统、数据库等方面。
下面是一个 3 阶 B 树
在这里插入图片描述
特点如下:
A、1 个节点可以存储超过 2 个元素,可以拥有超过 2 个子结点
B、拥有二叉搜索树的一些性质
C、平衡,每个节点的所有子树高度都一样
D、比较矮

  • m 阶 B 树的性质(m ≥ 2)

1、m 阶 B 树指的是一个结点最多拥有 m 个子结点。假设一个结点存储的元素个数为 x,那么如果这个结点是:
根结点:1 ≤ x ≤ m - 1
非根结点:┌ m / 2 ┐ - 1 ≤ x ≤ m - 1
2、如果有子结点,子结点个数为 y = x + 1,那么如果这个结点是:
根结点:2 ≤ y ≤ m
非根结点:┌ m / 2 ┐ ≤ y ≤ m
向上取整(Ceiling) 指的是取比自己大的最小整数,用数学符号 ┌ ┐ 表示;向下取整(Floor),指的是取比自己小的最大整数,用数学符号 └ ┘ 表示。
比如 m=3,子结点个数 2≤y≤3,这个 B 树可以称为(2,3)树、2-3 树。
比如 m=4,子结点个数 2≤y≤4,这个 B 树可以称为(2,4)树、2-3-4 树。
比如 m=5,子结点个数 3≤y≤4,这个 B 树可以称为(3,5)树、3-4-5 树。
以此类推。
在这里插入图片描述
这是一棵二叉搜索树,通过某些父子结点合并,恰好能与上面的 B 树对应。
我们可以得到结论:
1、B 树和二叉搜索树,在逻辑上是等价的
2、多代结点合并,可以获得一个超级结点,且 n 代合并的超级结点,最多拥有 (2^n) 个子结点 (至少是 (2^n) 阶 B 树)

红黑树的定义与性质

红黑树是一种含有红黑节点且能够自平衡的二叉搜索树。

为了保证平衡,红黑树必须满足以下性质:
1、每个节点要么是红色,要么是黑色
2、根节点必须是黑色
3、叶节点(外部节点、空节点)是黑色
4、红色节点不能连续(也就是说,红色节点的孩子和父亲都是黑色)
5、对于每个节点、从该结点至 null(树尾端)的任何路径都包含所相同个数的黑色节点

红黑树与 B 树的等价交换

在这里插入图片描述
根据上面的性质,可以画出这样一棵红黑树。接下来对红黑树做等价变换,即将所有的红色结点上升一层与它的父结点放在同一行,这就很像一棵 4 阶 B 树,转换效果如下图所示。
在这里插入图片描述
可以得出结论:

  • 红黑树与 B 树(2-3-4树)具有等价性
  • 黑色节点和红色节点融合在一起,形成一个 B 树节点
  • 红黑树的黑色节点个数与4阶 B 树的节点总个数相等
红黑树的基本操作

当我们对一颗平衡二叉搜索树进行插入、删除的时候,很可能会让这颗二叉树失去平衡。为了保持平衡,需要对二叉树进行旋转操作。而红黑树能够达到自平衡,靠的是树的左旋和右旋。旋转都是局部来操作树的结构:当一侧子树的节点少了,像另外一侧“借”一些节点,当一侧子树的节点多了,就将多余的节点“租”给另一侧。
为了搞清楚下面讲的内容,我们先应该熟悉一些下面定义的这些变量:

N-node :当前节点
P-parent:父节点
S-sibling:兄弟节点
U-Uncle:叔父节点(p的兄弟节点)
G-grand:祖父节点(p的父节点)

  • 左旋

左旋指的是,以某一个节点作为支点(旋转节点),其右子结点变为旋转节点的父节点,右子节点的左子节点变为旋转节点的右子节点,左子节点保持不变。
在这里插入图片描述

  • 右旋
    右旋指的是,以某一个节点作为支点(旋转节点),其左子结点变为旋转节点的父节点,左子节点的右子节点变为旋转节点的左子节点,右子节点保持不变。

在这里插入图片描述

  • 变色规律

将左旋、右旋和变色结合起来,得到下面一套变色规律
变色:如果当前节点的父节点和叔父节点都是红色

  • 把父节点和叔父节点变为黑色
  • 把祖父节点变为红色
  • 把指针定义到祖父节点

左旋:当前节点是做右子树,且父节点是红色,叔父节点是黑色,对它的父节点进行左旋。
右旋:当前节点是左子树,且父节点是红色,叔父节点是黑色,那么

  • 把父节点变为黑色
  • 把祖父节点变为红色
  • 对祖父节点右旋
红黑树搜索

由于红黑树本来就是二叉搜索树,并且搜索也不会破坏二叉树的平衡性,所以搜索算法也与平衡二叉搜索树一致:
在这里插入图片描述
具体步骤如下:

  • 从根节点开始检索,把根节点设置为当前节点。
  • 若当前节点为空,返回null。
  • 若当前节点不为空,比较当前节点对应的key和搜索key的大小。
  • 若当前节点的key=搜索的key,那么该key就是要找的节点,返回当前节点。
  • 若当前的key > 搜索的key,把当前节点的左子树节点设置为当前节点,重复步骤二。
  • 若当前的key < 搜索的key,把当前节点的右子树节点设置为当前节点,重复步骤二。
红黑树插入
  • 定位插入位置

在这里插入图片描述
具体步骤如下:

  • 从根节点开始检索。
  • 当根节点为空,直接插入待插入的节点做为根节点,插入结束。
  • 若根节点不为空,把根节点设置为当前节点。
  • 若当前节点为空,返回当前节点的父节点,插入结束。
  • 若当前节点的key = 待插入节点的key,那么该key所在节点就是带插入节点的插入位置,这时候更新节点的值,插入结束。
  • 若当前节点的key > 待插入节点的key,把当前节点的左子树节点设置为当前节点,重复步骤二。
  • 若当前的key < 待插入节点的key,把当前节点的右子树节点设置为当前节点,重复步骤二。
  • 插入后实现自平衡

建议新插入的节点默认为红色,因此这样可以尽快满足红黑树的性质,如果插入节点为根节点,默认为黑色。这里总结一下红黑树的插入可能的场景:
在这里插入图片描述###### 红黑树删除

  • 定位删除的位置

定位位置的话,可以复用红黑树搜索的操作。
如果不存在目标节点,忽略本次操作;如果找到了目标节点,删除后进行自平衡处理。

  • 删除后的自平衡
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值