JS怎样操作红黑树

这次给大家带来JS怎样操作红黑树,JS操作红黑树的注意事项有哪些,下面就是实战案例,一起来看一下。

红黑树的性质

一棵满足以下性质的二叉搜索树是一棵红黑树

每个结点或是黑色或是红色。

根结点是黑色的。

每个叶结点(NIL)是黑色的。

如果一个结点是红色的,则它的两个子结点都是黑色的。

对每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点。

性质1和性质2,不用做过多解释。

JS怎样操作红黑树

性质3,每个叶结点(NIL)是黑色的。这里的叶结点并不是指上图中结点1,5,8,15,而是指下图中值为null的结点,它们的颜色为黑色,且是它们父结点的子结点。

JS怎样操作红黑树

性质4,如果一个结点是红色的(图中用白色代替红色),则它的两个子结点都是黑色的,例如结点2,5,8,15。但是,如果某结点的两个子结点都是黑色的,该结点未必是红色的,例如结点1。

性质5,对每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点。例如,从结点2到其所有后代叶结点的简单路径上,黑色结点的数量都为2;从根结点11到其所有后代叶结点的简单路径上,黑色结点的数量都为3。

这样的一棵树有什么特点呢?

通过对任何一条从根到叶结点的简单路径上各个结点的颜色进行约束,红黑树确保没有一条路径会比其他路径长出2倍,因为是近似于平衡的。——《算法导论》

由于性质4,红黑树中不会出现两个红色结点相邻的情形。树中最短的可能出现的路径是都是黑色结点的路径,树中最长的可能出现的路径是红色结点和黑色结点交替的路径。再结合性质5,每条路径上均包含相同数目的黑色结点,所以红黑树确保没有一条路径会比其他路径长出2倍。

红黑树的插入

首先以二叉搜索树的方式插入结点,并将其着为红色。如果着为黑色,则会违背性质5,不便调整;如果着为红色,可能会违背性质2或性质4,可以通过相对简单的操作,使其恢复红黑树的性质。

一个结点以二叉搜索树的方式被插入后,可能出现以下几种情况:

情形1

插入结点后,无父结点,结点插入成为根结点,违背性质2,将结点调整为黑色,完成插入。

情形2

插入结点后,其父结点为黑色,没有违背任何性质,不用调整,完成插入。例如下图中插入结点13。

JS怎样操作红黑树

情形3

插入结点后,其父结点为红色,违背了性质4,需要采取一系列的调整。例如下图中插入结点4。

JS怎样操作红黑树

那么一系列的调整是什么呢?

如果插入结点node的父结点father为红色,则结点father必然存在黑色的父结点grandfather,因为如果结点father不存在父结点的话,就是根结点,而根结点是黑色的。那么结点grandfather的另一个子结点,我们可以称之为结点uncle,即结点father的兄弟结点。结点uncle可能为黑色,也可能为红色。

先从最简单的情形分析,因为复杂的情形可以转化为简单的情形,简单的情形就是结点uncle为黑色的情形。

JS怎样操作红黑树

情形3.1

如上图(a)中,情形是这样的,node 为红,father 为红,grandfather 和 uncle 为黑,α,β,θ,ω,η 都是结点对应的子树。假设整棵二叉搜索树中,只有node和father因违背性质4而无法成为正常的红黑树,此时将图(a)调整成图(b),则可以恢复成正常的红黑树。整个调整过程中实际分为两步,旋转和变色。

什么是旋转?

JS怎样操作红黑树

如上图(c)是一棵二叉搜索树的一部分,其中 x, y 是结点,α,β,θ 是对应结点的子树。由图可知,α

node 为红,father 为红,grandfather 和 uncle 为黑的具体情形一

图(a)中,node 为 father 的左子结点, father 为 grand 的左子结点,node

变色

所以图(a)旋转过后,还要将 grand 变为红色,father 变为黑色,变成图(b),完成插入。

node 为红,father 为红,grandfather 和 uncle 为黑的具体情形二

node 为 father 的右子结点, father 为 grand 的右子结点,如下图(e),就是具体情形一的翻转。

JS怎样操作红黑树

即,uncle

node 为红,father 为红,grandfather 和 uncle 为黑的具体情形三

node 为 father 的右子结点, father 为 grand 的左子结点,如下图(m)。

JS怎样操作红黑树

将图(m)中 node 和 father 旋转后,变成图(n),将father看作新的node,就成为了具体情形一,再次旋转,变色后,完成插入。

node 为红,father 为红,grandfather 和 uncle 为黑的具体情形四

node 为 father 的右子结点, father 为 grand 的左子结点,如下图(i),就是具体情形三的翻转。

JS怎样操作红黑树

将图(i)中 node 和 father 旋转后,变成图(j),将father看作新的node,就成为了具体情形二,再次旋转,变色后,完成插入。

情形3.2

node ,father 和 uncle 为红,grandfather 为黑。

JS怎样操作红黑树

如上图(k),不旋转,而是将grand着红,father和uncle着黑,同时将grand作为新的node,进行情形的判断。如果grand作为新的node后,变成了情形2,则插入完成;如果变成了情形3.1,则调整后,插入完成;如果仍是情形3.2,则继续将grand,father和uncle变色,和node结点上移,如果新的node结点没有父节点了,则变成了情形1,将根结点着为黑色,那么插入完成。

综上

node的情形 操作

情形1node为红,无father将node重新着色情形2node为红,father为黑情形3.1node,father为红,grand,uncle为黑旋转一次或两次,并重新着色情形3.2node,father,uncle为红,grand为黑将father, uncle,grand重新着色, grand作为新的node

代码

// 结点function Node(value) { this.value = value this.color = 'red' // 结点的颜色默认为红色 this.parent = null this.left = null this.right = null}function RedBlackTree() { this.root = null}RedBlackTree.prototype.insert = function (node) { // 以二叉搜索树的方式插入结点 // 如果根结点不存在,则结点作为根结点 // 如果结点的值小于node,且结点的右子结点不存在,跳出循环 // 如果结点的值大于等于node,且结点的左子结点不存在,跳出循环 if (!this.root) { this.root = node } else { let current = this.root while (current[node.value <= current.value ? 'left' : 'right']) {  current = current[node.value <= current.value ? 'left' : 'right'] } current[node.value  tree.insert(new Node(i)))debugger

登录后复制

相信看了本文案例你已经掌握了方法,更多精彩请关注【创想鸟】其它相关文章!

推荐阅读:

jQuery实现输入文字超过规定行数时自动添加省略号

JS中EL表达式获取相关元素参数

Vue自定义动态组件使用分析

以上就是JS怎样操作红黑树的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2765044.html

(0)
上一篇 2025年3月8日 10:39:41
下一篇 2025年3月8日 10:39:58

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • js构建二叉树数组去重与优化步骤详解

    这次给大家带来js构建二叉树数组去重与优化步骤详解,js构建二叉树数组去重与优化的注意事项有哪些,下面就是实战案例,一起来看一下。 前言 本文主要介绍了关于js构建二叉树进行数值数组的去重与优化的相关内容,分享出来供大家参考学习,下面话不多…

    编程技术 2025年3月8日
    200
  • js实现滑动拼图验证效果(附代码)

    这次给大家带来js实现滑动拼图验证效果(附代码),js实现滑动拼图验证效果的注意事项有哪些,下面就是实战案例,一起来看一下。   上图为网易云盾的滑动拼图验证码,其应该有一个专门的图片库,裁剪的位置是固定的。我的想法是,随机生成图片,随机生…

    2025年3月8日 编程技术
    200
  • JS实现鼠标触发悬浮层效果

    这次给大家带来JS实现鼠标触发悬浮层效果,JS实现鼠标触发悬浮层效果的注意事项有哪些,下面就是实战案例,一起来看一下。 在人人,CSDN等一些网站,当鼠标在某个东西上悬浮时,会弹出一个悬浮层,鼠标移开悬浮层消失。 比如说CSDN的通知(应该…

    2025年3月8日
    200
  • vue中如何使用jointjs属性

    这次给大家带来vue中如何使用jointjs属性,vue中使用jointjs属性的注意事项有哪些,下面就是实战案例,一起来看一下。 在vue中引入joint.js的问题,之前在网上搜了很多,都没有给出一个确切的答案,捣鼓了两天终于弄明白了,…

    编程技术 2025年3月8日
    200
  • Node.js注册邮箱激活有哪些方法

    这次给大家带来Node.js注册邮箱激活有哪些方法,Node.js实现注册邮箱激活的注意事项有哪些,下面就是实战案例,一起来看一下。 在做自己的node项目极客教程时,需要开发一个注册邮箱激活的功能,这个功能非常常见,当我们注册一个账号时,…

    2025年3月8日
    200
  • JS常用函数总结归纳

    这次给大家带来JS常用函数总结归纳,使用JS常用函数的注意事项有哪些,下面就是实战案例,一起来看一下。 数组扁平化 数组扁平化有很多方法,但最终最好的方法就是递归,实现一个指定深度的扁平化方法,这样基本的套路都会了解。 function f…

    编程技术 2025年3月8日
    200
  • JS原始值与引用值有哪些储存方式

    这次给大家带来JS原始值与引用值有哪些储存方式,使用JS原始值与引用值储存方式的注意事项有哪些,下面就是实战案例,一起来看一下。 原始值指的是代表原始数据类型的值,也叫基本数据类型,包括:Number、Stirng、Boolean、Null…

    2025年3月8日
    200
  • JS动画定时器使用详解

    这次给大家带来JS动画定时器使用详解,JS动画定时器使用的注意事项有哪些,下面就是实战案例,一起来看一下。 广义说:一切通过js改变的视觉呈现都叫动画;例如,按钮,链接等元素交互反馈。 狭义说:通过定时器连续调用js函数进行元素属性改变产生…

    2025年3月8日
    200
  • 毕达哥拉斯树怎样用JS实现

    这次给大家带来毕达哥拉斯树怎样用JS实现,毕达哥拉斯树用JS实现的注意事项有哪些,下面就是实战案例,一起来看一下。 效果如下: 主要方法 translate() rotate() rect() push() pop() map() 主要思想…

    2025年3月8日
    200
  • js-cookie使用步骤详解

    这次给大家带来js-cookie使用步骤详解,js-cookie使用的注意事项有哪些,下面就是实战案例,一起来看一下。 Cookie是网站设计者放置在客户端的小文本文件,一般后台语言使用的比较多,可以实现用户个性化的一些需求。js-cook…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论