首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Javascript:需要一个体面的红黑树实现

在JavaScript中,红黑树是一种数据结构,用于在插入和删除操作过程中保持树的高度相对较低,从而提高性能。在实现红黑树时,需要满足以下五个性质:

  1. 节点是红色或黑色。
  2. 根节点是黑色。
  3. 所有叶子节点(叶子节点通常是指NIL或空节点)是黑色。
  4. 如果一个节点是红色,那么它的两个子节点都是黑色。
  5. 对于每个节点,从该节点到其所有后代叶子节点的路径上,黑色节点的数量必须相同。

实现红黑树的常用算法是“B树”,它是一种自平衡的二叉搜索树。B树在插入和删除操作过程中会重新调整树的结构,以保持树的平衡。

在JavaScript中,可以使用红黑树实现来提高程序的性能,尤其是在需要频繁插入和删除元素的场景下。例如,在实现一个编辑器时,可以使用红黑树来存储和排序文档中的单词,以便快速查找和修改文档。

以下是一个简单的JavaScript红黑树实现:

代码语言:javascript
复制
class Node {
  constructor(val) {
    this.val = val;
    this.left = null;
    this.right = null;
    this.color = 1; // 默认为红色
  }
}

class RedBlackTree {
  constructor() {
    this.root = null;
  }

  insert(val) {
    const newNode = new Node(val);
    if (this.root === null) {
      this.root = newNode;
    } else {
      this._insert(this.root, newNode);
    }
  }

  _insert(node, newNode) {
    if (newNode.val < node.val) {
      if (node.left === null) {
        node.left = newNode;
      } else {
        this._insert(node.left, newNode);
      }
    } else {
      if (node.right === null) {
        node.right = newNode;
      } else {
        this._insert(node.right, newNode);
      }
    }

    if (newNode.color === 1) {
      this._setBlack(node);
    } else {
      this._setRed(node);
    }
  }

  _setBlack(node) {
    node.color = 0;
    if (node.left !== null) {
      this._setBlack(node.left);
    }
    if (node.right !== null) {
      this._setBlack(node.right);
    }
  }

  _setRed(node) {
    node.color = 1;
    if (node.left !== null) {
      this._setRed(node.left);
    }
    if (node.right !== null) {
      this._setRed(node.right);
    }
  }

  remove(val) {
    this.root = this._remove(this.root, val);
  }

  _remove(node, val) {
    if (node === null) {
      return null;
    }

    if (node.val === val) {
      if (node.left === null) {
        return node.right;
      }
      if (node.right === null) {
        return node.left;
      }
      const pivot = node.right;
      this._rotate(node);
      this._remove(pivot, val);
    } else if (node.val < val) {
      node.right = this._remove(node.right, val);
    } else {
      node.left = this._remove(node.left, val);
    }

    return node;
  }

  _rotate(node) {
    const pivot = node.right;
    node.right = pivot.left;
    if (pivot.left !== null) {
      pivot.left.parent = node;
    }
    pivot.parent = node.parent;
    if (node.parent === null) {
      this.root = pivot;
    } else if (node === node.parent.left) {
      node.parent.left = pivot;
    } else {
      node.parent.right = pivot;
    }
    pivot.left = node;
    node.parent = pivot;
  }
}

这个实现中,`Node

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

():构建

篇文章就来看看如何构建 对于平衡二叉的构建,可以参考小程序中的文章(C++版)。...平衡二叉 属于平衡二叉,但是并非严格意义上的平衡二叉,因为平衡二叉要求节点的左右子树高度差不超过1, 而放弃了这种高度平衡,利用对结点上色的操作来保证相对平衡,这其中原因大概是维护个绝对平衡的二叉代价太大...但如果插入频率小或者只有次构建,那么平衡二叉的查询性能还是比高。...从上面的性质我们大概知道的结构,树根为黑色,不存在连续的两个红色结点,每个子树分支的结点个数相同,如下图 ?...到这里就构建完成了 相对于构建新增,的删除情况更为复杂,由于时间关系(这周只有天休息加上绘图太费劲),留到下次分享。 构建代码 构建源码

1.7K42
  • 实现

    在数据结构中,如果提到编码和压缩绕不开 Hoffman ,如果从快速获取搜索的树结构那么就离不开,哈希表设计中,从数组加链表,不行我就数组加,大名鼎鼎的 epoll 也开始起了...的规定很是难以理解,其他的五大特性如下:每个结点是的或者的根结点是的每个叶子结点是的如果个结点是的,则它的两个儿子都是的对每个结点,从该结点到其子孙结点的所有路径上的包含相同数目的结点当然面对这样的定义很多人其实会很困惑...代码实现有了定义,那就废话不多说,从代码开始讲起。数据结构首先就是我们需要定义这样的数据结构,首先就是我们需要定义的每个节点的情况。...,但是实际添加需要对红各种边界做出判断,因此需要定义如下几个函数。...结语的操作其实较为死板和公式化,只不过需要考虑的分支较多,只要仔细深入各个分支进行写代码就很简单。

    13000

    的模拟实现

    前言 我在前面的文章中,已经详细讲解了二叉搜索(二叉搜索的模拟实现-CSDN博客)、AVL(AVL模拟实现-CSDN博客)的模拟实现,终于,我要讲解啦~~~,让我们进入正题吧 ヾ(≧▽≦*...)o 概念 也是棵二叉搜索,它有如下特点 1、每个节点不是红色就是黑色 (从树名字就可得知) 2、根节点是黑色的 (这是检查是否正确的个判断条件) 3、如果个节点是红色的...,均包含相同数目的黑色节点 (这是检查是否正确的个判断条件) 这些特点使得效率也很高,因为他们构成了个大特点: 最长路径的节点个数 <= 2 * 最短路径的节点个数 为什么满足...,诞生了 的模拟实现 “颜色”定义 虽然有颜色,但是红色和黑色并不是真的颜色,而是用了枚举enum的知识,将字符串转化为数字(内部),因此黑色红色的定义就是个枚举 enum COLOR {...我们进行第三步 (3) 叔叔变为黑色 如下图所示 细心的读者可能会发现:爷爷的颜色变为红色了 在这个非的树下,我们就需要对“红色”极其敏感 这里爷爷不定是祖先,所以,我们应该注意爷爷的父亲是什么颜色

    7710

    原理及实现

    也是种平衡二叉应用广泛,linux内核的rbtree.c,jdk的TreeMap和HashMap等都实现树结构。写的性质前,先按照自己的思维去考虑,为什么这样定义。...由情况二变为情况三,然后情况三变化如下 总结:的插入在违反规则4的时候有三种情况,其中情况1情况3都可以次旋转是当前子树符合性质,并且情况3使得整个都符合性质,情况需要向上回溯判断是否符合性质...解释:这种情况无法次转为符合性质的需要转换为以下三种情况的任意种。 调整结点6。  ...解释:这种情况和插入情况中的第二种情况样,都需要转换为最后种情况,因为最后种情况可以通过次变换达到符合性质。  ...2.删除第三种情况和插入第二种情况也类似,这种情况下树的形态都不能次性转化为满足性质的形态,都需要次中转,变成可以通过次操作满足性质的形态。

    55810

    TypeScript实现AVL

    :故名思义,即中的节点不是的就是的,它也是个自平衡二叉。...上面我们实现了AVL,我们在向AVL中插入或移除节点可能会造成旋转,所以我们需要个包含多次插入和删除的自平衡是比较好的。插入或删除频率比较低,那么AVL更好。...实现思路 的每个节点都需要遵循以下原则: 节点不是的就是的根节点是的 所有叶节点都是的 如果个节点是的,那么它的两个子节点都是的 不能有两个相邻的节点,节点不能有的父节点或子节点...插入节点 向中插入节点的逻辑与二叉样,除了插入的逻辑外,我们还需要在插入后给节点应用种颜色,并且验证是否满足的条件以及是否还是自平衡的。...我们需要创建个新的节点类用来描述: 节点的颜色、父节点的引用 重写insert方法,如果树是空的则创建个新的树节点作为根节点,将根节点的颜色设为黑色 如果插入时,不为空我们会像二叉搜索样在正确的位置插入节点

    51010

    玩转:手把手教你实现和理解

    1.2、代码实现了解了理论,就需要代码上进行实现。定义树节点结构体包含以下内容:定义个颜色标识符。定义左子树和右子树的指针。定义执行父节点的指针。这个是为了做性质调整需要。...当阅读份项目源码时,如果看到个结构体包含颜色定义、左节点、右节点、父节点时,可以大概率确定它是了。1.3、代码优化上面的定义是否存在些问题呢?...最大的问题是这个的定义不可复用,它的业务和实现是黏在起的,可迁移性低。为了提高通用性和灵活性,可以将的定义做成模板化,将的性质封装在起。...右旋与左旋同理,它们是个互逆的过程。以根结点示例:小结:插入或删除节点,最多需要旋转的次数是的高度。2.2、代码实现(1)左旋。左旋函数的实现需要带哪些形参呢?答案是头节点和旋转节点。...总结需要理解的难点:性质、旋转、插入、删除。种二叉,中序遍历绝对有序。当红的性质被破环时,需要触发旋转,进行调整。旋转有两种方式:左旋和右旋。

    13700

    工作不需要面试需要知识

    写在前面 ,对很多童鞋来说,是既熟悉又陌生。学校中学过,只了解大概;工作中不怎么使用,但面试又是重点。每次需要查看内容时都很难以更生动形象的方式来理解其内容。...「去除顶端优势」,通过去除植物顶端优势,侧芽会迅速生长,慢慢变得强壮和平衡, 其实就是去除二叉查找树顶端优势的解决方案,从而达到的平衡 ,Red-Black Tree 「RBT」是个自平衡...(不是绝对的平衡)的二叉查找(BST),树上的每个节点都遵循下面的规则: 每个节点都有红色或黑色 的根始终是黑色的 (黑土地孕育树根,) 没有两个相邻的红色节点(红色节点不能有红色父节点或红色子节点...样,有两大操作: recolor (重新标记黑色或红色) rotation (旋转,这是达到平衡的关键) 我们会先尝试 recolor,如果 recolor 不能达到的 4 点要求...,将其改为黑色 继续插入其他节点只不过反复应用上面的公式,上面应用到的工具,可以暂停动画效果,帧的看的转换过程,这样通过练习,查看公式,观察变化三管齐下,的入门理解应该完全不再是问题了

    32020

    手写(C++实现

    从任何个节点到其每个叶子节点的路径上都包含相同数目的黑色节点。 本文将带你步步实现的基本功能,包括插入、删除和搜索等操作。我们使用C++语言来实现的数据结构和算法。...了解实现细节,可以帮助你更好地理解其原理和特性。下面我将介绍实现流程,帮助你对其有更全面的了解。...实现细节包括以下几个方面:结构定义:首先,我们需要定义的结构,包括树节点的属性和方法。...node.color = "BLACK"这是个基本实现,但实际上还有许多细节需要考虑,例如的查找、旋转等操作,以及对应的辅助函数的实现。...实现还有很多变种和优化,涉及更多的特殊情况处理和平衡性维护。但是通过了解这个基本的实现流程,你应该可以更好地理解的原理和特性,并能够自己实现个简单的

    32710

    如何利用实现排名?

    问题 ---- 种自平衡的二叉查找,它可以在O(logn)时间内执行查找、插入和删除。在c++ STL,linux内核中都有使用。...根据的递归性质,我们只需要在每个节点增加个字段count用来统计当前节点子树的个数,同时在做插入、删除操作的时候更新count字段,就能在O(logn)的时间内查询到该元素的排名。 3....实现 ---- 树节点增加count字段,count[x]表示x节点子节点元素的个数,包括它的左子树,它的右子树和它自己本身。...增加count扩展后,增加的count操作主要在的旋转,每次平衡最多3次旋转,所以对红的性能影响很小,可以用来实现游戏中常见的排行榜功能。...但是当元素集合的总量达到定规模比如千万级,可能会有性能问题,主要消耗在key的字符串比较上。

    2.2K31

    【C++】模拟实现

    .了解项目功能 在本次项目中我们的目标是实现类模板,还不了解概念的朋友可以先移步[【数据结构】什么是(Red Black Tree)?]...(RBTreeNode)逻辑结构图示如下: 类模板提供的功能有: 结点类的构造函数 的构造函数 的插入函数 左单旋函数 右单旋函数 判断是否符合规则函数...实现RBTreeNode类模板 构造RBTreeNode类成员变量 我们在开始需求分析时就已经明确了结点(RBTreeNode)需要包含五个成员:键值对_kv, 左指针域_left...: enum Colour { RED, BLACK }; 这里还有个小的点需要下,我们在这里实现的RBTreeNode类,后续是要给RBTree类使用的,考虑到后续我们在的操作函数中会有直接操作结点成员变量的情况...判断是不是,就要从的几个规则出发,看其是否满足下面这几个规则: 每个结点不是红色就是黑色 根结点是黑色 如果个结点是红色的,则它的子结点定是黑色 任结点到NULL

    7810

    hashmap底层1.8有,什么是文了解

    种特殊的平衡二叉 满足如下几个条件: 1、结点是红色或黑色的 2、根结点始终是黑色的 3、叶子结点也都是黑色的 (当红色结点无左右孩子时,补足空结点是黑色的) 4、红色结点的子结点都是黑色的...5、对任结点,到叶子结点的所有路径,都包含相同数目的黑色结点 特征: 从根结点到叶子结点的最长路径,不会超过最短路径的两倍 当插入新结点使失去平衡时,通过两种方式恢复平衡: 旋转和变色 (...变黑 变红) 可视化网站:树结构可视化 插入结点到的逻辑 约定 新插入的结点都设为红色的,可以简化的平衡过程 假设要插入的结点是X 父结点是P 祖父结点是G 叔父结点是U 1)X是根结点

    58330

    深入剖析及Java实现

    是平衡二叉查找种。为了深入理解,我们需要从二叉查找开始讲起。...但是整颗定是符合定义的,需要往上追溯继续调整。...对于兄弟节点的子节点为左或者 (全部为,右)这两种情况,可以先将前面的情况通过选择转换为后种情况,在后种情况下,因为兄弟节点为,兄弟节点的右节点为,可以借调出两个节点出来做节点,...第个元素d是root节点,由于它没有父节点,所以括号内只有个元素。 总结 作为平衡二叉查找里面众多的实现无疑是最简洁、实现最为简单的。...面的插入和删除的操作比较难理解,这时要注意记住点:操作之前是平衡的,颜色是符合定义的。

    1.3K30

    Python实现的插入操作

    篇文章介绍了什么是,以及的旋转和变色。 参考:简介及左旋、右旋、变色 本文使用Python实现的插入操作。 先将的5条特性列出来: 1. 节点是红色或黑色。 2....四、实现的插入方法 开始是满足5条特性的,插入新节点后,如果特性被破坏了,就要进行调整,使重新满足5条特性。...插入新节点后,是否需要对红进行调整,以及怎么调整,分为如下几种情况: 1. 如果棵空,则将新节点添加到根节点的位置,并将节点的颜色修改为黑色。 2....在后面的3.2中,叔节点是节点时,进行第次调整后,还不定能调整完成,祖父节点成为新的因素节点,可能会出现因素节点F为、父节点P为、祖父节点G为、叔节点U为的情况。...实现的代码后,可以看出,每插入个新节点,都是满足5条特性的,而有定是个节点个节点地添加得到的。

    68230

    深入剖析及Java实现

    概述 (Red Black Tree) 是种自平衡二叉查找,是在计算机科学中用到的种数据结构,典型的用途是实现关联数组。...需要做的处理是从兄弟节点上借调黑色的节点过来,如果兄弟节点没有节点可以借调的话,就只能往上追溯,将每级的节点数减去个,使得整棵符合的定义。...但是整颗定是符合定义的,需要往上追溯继续调整。...第个元素d是root节点,由于它没有父节点,所以括号内只有个元素。 总结 作为平衡二叉查找里面众多的实现无疑是最简洁、实现最为简单的。...面的插入和删除的操作比较难理解,这时要注意记住点:操作之前是平衡的,颜色是符合定义的。

    97860

    超详细的模拟实现

    的介绍 ,是种二叉搜索,但在每个结点上增加个存储位表示结点的颜色,可以是Red或Black。...每个叶子节点(这里特指最下面的空节点)是黑色的。 如果个节点是红色的,则它的子节点必须是黑色的。...,也许我们会遇到各种问题,好不容易跑通代码后,我们缺无法判断自己实现是否正确,是否符合的规则。...此时,我们可以设计个检测函数,检测实现是否平衡。 空也是 根节点必须是 我们可以设置个“基准值”,基准值为条路径中的黑色结点的个数。...后续牛牛会模拟实现map和set,会在那篇文章封装,对红进行改造,增加迭代器等功能。帮助友友们更加深入理解map和set容器。

    14711

    插入操作的java实现

    前言 网上有非常多的关于理论的描述,本文的重点将不在于此,但是会在文中给出优秀文章的链接。对红不了解的建议先阅读文章再看实现。本实现不支持多线程环境。...数据结构 定义的的节点如下: private static class Node{ static final int RED = 0; static final...除此以外还封装了些方法,比如获得自己的祖父节点,叔叔节点以及兄弟节点等。 旋转操作 因为额外持有了父节点,所以在执行旋转操作的时候需要额外注意空指针以及不恰当的赋值带来的循环引用。...else { leftChild.parent = null; root = leftChild; } } 插入 我们知道,在中插入个节点相当于在个二叉搜索中插入个节点...因此该节点定是作为叶节点而插入的。二者唯的不同在于,默认插入的节点为红色,我们需要重新调整树结构从而确保重新达到平衡。

    74620

    Python实现的删除操作

    篇文章使用Python实现的插入操作。参考:Python实现的插入操作 本篇文章使用Python实现的删除操作。 先将的5条特性列出来: 1. 节点是红色或黑色。...二、实现的删除方法 的删除方法可以分两个步骤实现,第步是按照二叉搜索的方法将节点删除,第二步是对删除节点后的进行调整,使重新满足5条特性。...3.2 后继节点有个右子节点。 后继节点定是节点,后继节点的右子节点定是节点,调用上面的情况2,将后继节点删除。代码实现如下。...总结,的删除中,被删除节点是叶节点时最复杂,需要仔细分析每种情况。...所以,有必要实现个方法来对红进行自查,判断当前是否满足5条特性。

    89330

    的原理和TreeMap实现

    处理方法:什么也不需要做。节点被插入后,仍然是。 3.被插入的节点的父节点是红色。 处理方法:那么,该情况与的“特性(5)”相冲突。...将当作颗二叉查找,将节点删除。...步骤二:通过"旋转和重新着色"等系列来修正该,使之重新成为。 因为"第步"中删除节点之后,可能会违背的特性。...所以需要通过"旋转和重新着色"来修正该,使之重新成为。 下面仅考虑情况① 和情况②的调整。...()之 原理和算法详细介绍 ):插入 (二):删除 https://zhuanlan.zhihu.com/p/25440484 史上最清晰的讲解 彻底搞懂 图解

    41810
    领券