数据结构之二叉查找树(Binary Search Tree)和红黑树(Red Black Tree)

感兴趣的话大家可以关注一下公众号 : 猿人刘先生 , 欢迎大家一起学习 , 一起进步 , 一起来交流吧!

二叉查找树(Binary Search Tree)

二叉查找树又可以称之为 : 二叉搜索树 , 二叉排序树 , 它或者是一棵空树,或者是具有下列性质的二叉树:若它的左子树不空,则左子树上所有结点的值均小于它的根节点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉排序树。二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势 , 下图中这棵树,就是一棵典型的二叉查找树

图片

那么这样的数据结构有什么好处呢?

比如我们来查找一个元素 : 23

如果我们用链表来存储的话 : 查找元素23就需要一个一个遍历 , 直到找到匹配的元素

图片

如果使用二叉查找树来存储的话 , 查找元素23 , 首先和根节点20比较 , 发现比20大 , 那么就查找树右边的元素 , 发现比30小 , 那么就继续查找30左边的元素 , 发现比25小 , 那么就查找25左边的元素 , 这样一来 , 整个元素查找所消耗的时间远远的比遍历整个链表快了许多 , 这就是二叉查找树的思想 , 查找所需的最大次数等于这个树的高度

在插入结点的时候也是使用类似的方法 , 找到元素的位置然后插入 , 虽然看起来挺方便的 , 但是也有它的缺陷 , 比如这种情况 : 原有的树结构为这样(如下图所示) , 现在需要插入9,8,7,6,5这几个元素

图片

元素插入之后就变成这样了(如下图所示)

图片

可以发现 , 这样的存储和链表没什么太大的区别 , 虽然符合二叉查找树的特性 ,但是查找的性能大打折扣

那么如何解决二叉查找树多次插入新结点导致的不平衡呢?

这个时候红黑树诞生了 , 红黑树(Red Black Tree) 是一种自平衡的二叉查找树 , 它除了符合二叉查找树的基本特征外还包括了以下特征 :

  • 根节点必须是黑色的

  • 节点是红色和黑色

  • 每个叶子节点都是黑节点的空节点(NIL节点)

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

  • 从任意节点到每个叶子的所有路径上的黑色节点数量相同

    我们用下面的一张图来表示 :

图片

这个图看起来比二叉查找树的图复杂一点 , 正是有了这些规则的限制 , 才保证了红黑树的自平衡 , 红黑树从根到叶子的最长路径不会超过最短路径的2倍

当进行插入和删除节点操作的时候 , 这个树的平衡可能被打破 , 所以就需要一些措施来保证这个树的平衡 , 那么在什么情况下会打破这棵树的平衡呢? 下面来看几种例子

情况一 : 插入一个元素23

插入一个元素28之后 , 由于父亲节点是黑色节点 , 并不会打破红黑树的规则 , 所以没有问题

图片

情况二 : 插入一个元素33

图片

为什么插入的这个节点是红色的?

因为上面提到红黑树的第五个特征就是 : 从任意节点到每个叶子的所有路径上的黑色节点数量相同 , 所以这块不能是黑节点 , 只能是红节点

由于父亲节点是红色节点 , 因此打破了红黑树的规则 : 每个红色节点的两个子节点都是黑色的(从每个叶子到根的所有路径上不能有连续的两个红色节点) , 所以就必须做出调整 , 使它符合红黑树的规则

那么应该做出什么样的调整呢?

旋转(左旋右旋)变色

旋转和颜色变换规则:所有插入的点默认为红色

变色

变色的情况 : 当前节点的父节点是红色的 , 当前节点的叔叔节点是红色的

下面我们实际分析一下:

图片

现在我们插入一个节点33 , 由于新插入的节点是红色的 , 打破了红黑树的平衡 , 所以要进行旋转变色来维持这个平衡

首先就是判断是旋转还是变色: 33的父节点是红色 , 叔叔节点也是红色 , 符合变色规则

先把父亲节点35变为黑色 , 再把叔叔节点45变为黑色 , 把爷爷节点40变为红色

图片

由于40的父亲节点30和叔叔节点10也都是红色 , 所以要继续改变颜色 , 把父亲节点30变为黑色 , 把叔叔节点10变为黑色 , 爷爷节点20变为红色

图片

由于爷爷节点是根节点 , 根节点只能为黑色 , 所以变色为黑色 , 这样 , 我们得到了一棵新的红黑树

图片

左旋

当前父结点是红色,叔叔是黑色的时候,且当前的结点是子树 , 以父节点为中心逆时针旋转,使得父节点被自己的右孩子取代,而自己成为自己的左孩子

图片

插入一个元素41

图片

这个时候红黑树的规则又被破坏了 , 继续进行判断 , 发现符合变色的条件 , 进行变色

图片

变色完成之后 , 发现40和35又破坏了红黑树的规则 , 继续进行判断 , 40的父节点是红色 , 叔叔节点是黑色的 , 不符合变色的条件了 , 但是符合左旋转的条件 , 所以以父节点为中心逆时针旋转进行左旋

图片

左旋之后 , 发现35和40节点还是不符合红黑树的规则 , 也不符合变色和左旋的规则 , 所以我们接着这个结果在下面分析右旋

右旋

当前节点的父节点是红色的 , 叔叔节点是黑色的 , 且当前节点是左子树 , 以自己的爷爷节点为中心顺时针旋转 , 使得父节点被自己的左孩子取代,而自己成为自己的右孩子

接着上面左旋的结果来分析 , 由于符合右旋的结果 , 所以我们围绕父节点40来进行顺时针旋转 , 旋转后结果如下

图片

右旋之后40节点成为了根节点 , 由于根节点只能是黑色 , 所以进行变色

图片

变色之后发现还是不满足红黑树的规则4 , 所以把45节点再进行变色

图片

插入新节点41之后 , 经过一系列的旋转变色操作 , 最终得到了一棵红黑树

以上我们通过图文的方式简单的分析了红黑树的旋转变色 , 在实际的插入删除中 , 还涉及到很多的条件 , 这里就不一一列举了 , 主要体会红黑树自平衡调整的主体思想

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
查找Binary Search Tree,BST)和Red-Black Tree)是两种常见的二数据结构,它们在插入、删除和查找等操作上有一些区别。 1. 结构特点: - 二查找:每个节点的左子中的所有节点的值都小于该节点的值,右子中的所有节点的值都大于该节点的值。 - :除了具备二查找的特点外,还满足以下性质: - 每个节点要么是色,要么是色。 - 根节点是色。 - 每个叶子节点(NIL节点,空节点)是色。 - 如果一个节点是色的,则它的两个子节点都是色的。 - 对于每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的色节点。 2. 平衡性: - 二查找:在最坏情况下,二查找可能会退化成链表,导致插入、删除和查找操作的时间复杂度为O(n)。 - :通过保持性质,能够保持相对平衡,插入、删除和查找操作的时间复杂度为O(log n)。 3. 插入和删除操作: - 二查找:插入和删除操作只需按照二查找的规则进行即可,不需要进行额外的平衡操作。 - :插入和删除操作需要通过旋转和重新着色等操作来保持的平衡性。 4. 存储空间: - 二查找:每个节点只需存储键值和指向左右子节点的指针,相对较小。 - :每个节点需要额外存储颜色信息,相对于二查找会占用更多的存储空间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lingering fear

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值