迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Java >

Java 中的红黑树

作者:迹忆客 最近更新:2023/11/13 浏览次数:

本文对最著名的数据结构技术之一红黑树进行了最新和深入的检查。此外,我们还针对我们认为你必须理解的基本元素执行了一些 Java 演示程序。

尽管本文结合了红黑树的所有基本特征,但我们的目标是使其尽可能简单。但是,我们也知道初学者理解这个主题可能具有挑战性。


红黑树

红黑树是计算机科学中独特的二叉搜索树,特别是在数据结构和算法方面。我们使用它来对复杂问题陈述的可比较数据位进行分组。

下表包含有关红黑树的一般信息。

No. 树的类型 自分支,二叉搜索树
1 创造者 鲁道夫拜耳
2 函数 搜索、插入、检测
3 空间复杂度 O(n)
4 时间复杂度 O(log n)

图 1:典型的红黑树(演示示例)。

红黑树

红黑树的性质

红黑树必须满足以下条件。

  1. 每个节点都有红色或黑色。
  2. 我们将 NIL (= NONE)- 孩子`` 称为树的叶子。
  3. 每个 NIL-leaf 都是黑色的。
  4. 树的根也必须是黑色的。
  5. 假设一个节点是红色的,那么这个节点的两个孩子都必须是黑色的。
  6. 从节点到后代叶子的所有路径必须包含相同数量的每个节点的黑色节点。

红黑树的高度定义

图 2:树的黑色高度。

红树的高度和黑色高度

树中节点的属性

树节点应包含以下属性。

  1. 颜色
  2. 左孩子
  3. 右孩子
  4. 父节点(不包括根节点)

以下是我们稍后将如何处理 Java 程序中的节点。

// class node
public class BlackRedTreeNode {
  int Ndata; // The data of the node
  BlackRedTreeNode P; // parent
  BlackRedTreeNode L; // Left
  BlackRedTreeNode R; // Right
  int Nclr; // Color of the node
} // end of class

确定红黑树的平衡

我们将假设使用一种数据结构算法的方法来解决如何平衡红黑树结构的问题陈述。

节点颜色限制确保从根到叶的任何简单路径不超过任何其他此类路径的两倍。它增加了红黑树的自平衡能力。

  1. 节点高度:Hn
  2. T 作为树

你可以看到通往叶子的最长路径的边缘。

  1. node-x 的黑色高度:

bh(x) 表示黑色节点的数量,包括从 x 到叶子的路径上的 nil [T],但不包括 x

  1. 无叶子:

树中的这些属性仅用于计数(属性编号 6)。

  1. 引理:具有 n 个节点的红黑树的高度:


    $$
    ≤ 2 log (n+1)
    $$

  2. 证明:以任意节点 x 为根的子树至少包含:


    $$
    2^bh(x) -1
    $$

因此,黑色高度为 bh(x) 的最小子树和完整树具有 n 个内部节点:


$$
2^bh(root[T]) -1 ≤ n
$$


红黑树中的子树旋转

旋转是为自平衡二叉搜索树设计的独特操作,需要 O(1) 才能完成。此外,相同的旋转有助于保持键的有序遍历。

此外,在旋转操作期间交换子树节点的位置。当其他操作,如插入和删除,违反了红黑树的属性时,会执行旋转操作来恢复它们。

旋转分为两种:

左右旋转

被评估的节点的阿姨会影响进行旋转或颜色更改(当前节点)的选择。如果节点有黑阿姨,我们就轮换。

如果节点有一个红色阿姨,我们反转颜色。我们必须在旋转树后对其进行颜色修复。

在这些操作之后,树应该被终止,如下所示。

旋转后

右旋转的示例 Java 代码:

// function
// n as node
// P as Parent
// R as Right
// L as Left
// LC as LeftChild
private void RightRotation(TreeNode n) {
  TreeNode paPrent = n.P;
  TreeNode LC = n.L;
  n.L = LC.R;
  if (LC.R != null) {
    LC.R.P = n;
  }
  LC.right = n;
  n.P = LC;
  Replace(P, n, LC);
} // end of function

Java 中的左旋转示例:

// function left rotation
private void LeftRotation(TreeNode n) {
  TreeNode P = n.P;
  TreeNode Rc = n.R;
  n.R = Rc.L;
  if (Rc.L != null) {
    Rc.left.P = n;
  }
  Rc.left = n;
  n.P = Rc;
  replace(P, n, Rc);
} // end of function

搜索算法:红黑树

搜索的工作方式与任何二叉搜索树的工作方式相同。我们首先将搜索键与根进行比较。

如果你的搜索关键字较小,则在左子树中继续搜索;如果搜索关键字更重要,则在右子树中继续搜索。

我们重复这个过程,直到找到我们想要的节点。换句话说,直到我们到达一个零叶点。

假设我们到达一个零叶子,这意味着我们正在寻找的键不在树中。

代码:搜索

// Sn as Search Nodes
// k as Key
// n as node
// r as Right
// d as Data of the data
// L as left
// Function starts here
public TreeNode Sn(int k) {
  TreeNode n = r;
  // determine the search by applying while loop
  //  loop starts
  while (n != null) {
    // checking the key
    if (k == n.d) {
      return n;
    } else if (k < n.d) {
      n = n.L;
    } else {
      n = n.R;
    } // condition ends
  } // loop ends
  return null;
} // Function ends here

插入:红黑树 Java

下面的程序演示了一个函数,我们可以使用它在黑红树中插入节点。尽管就数据结构的观点而言它遵循正确的顺序,但完整的执行将因你的方法而异。

下面的代码对于初学者来说还是足够了,尤其是对于初学者。

代码:插入

// iN as insertion node
//  k as key of the tree
// r as root of the node
// R as right node
// L as left node
// d as data
// p as parent
public void iN(int k) {
  TreeNode n = r;
  TreeNode P = null;
  // Swaping the nodes
  while (n != null) {
    p = n;
    if (k < n.d) {
      n = n.L;
    } else if (k > n.d) {
      n = n.R;
    } else {
      throw new IllegalArgumentException(
          "The Binary Search Tree  already has a node with this key: " + k);
    }
  }
  // A rough example of how you can apporach insertion of the new node in the tree using BST
  TreeNode newN = new TreeNode(k);
  newN.clr = red;
  if (p == null) {
    r = newN;
  } else if (k < p.d) {
    p.L = newN;
  } else {
    pt.R = newN;
  }
  newN.p = p;
  // Fixing the tree after the insetion
  fixingTreeAfterInsertion(newN);
}

红黑树的应用

在 Java 集合库中,红黑树已用于 TreeSetTreeMapHashmap。它也用于 Linux 内核:Completely Fair SchedulerFileMemoryMapping

此外,Linux 在 mmapmunmap 操作中使用它。此外,它们还用于降低 K-mean 聚类算法的时间复杂度。

此外,MySQL 为表搜索实现了红黑树。我们为什么用它?

红黑树确保 O(log(n)) 的插入和删除时间。它们是稳定的搜索树,因此,它们始终保持对数高度 (n)。

考虑将整数 1,2,3,4,5 放入二叉树中。它将 1 设为根,所有后续元素将向右移动,形成一个有效的链表(并且每个操作都需要 O(n) 时间)。

即使平均时间复杂度相同,如果我们考虑最坏的情况,红黑树在时间复杂度方面超过二叉搜索树。


概括

本教程教你什么是红黑树、控制它的规则以及如何评估这些规则。我们还粗略地演示了如何使用 Java 程序来处理它。

本教程中的一些重要内容:

一、红黑树简介
2. 典型的红黑树:演示示例
3. 树中节点的属性
4. 利用数据结构确定红黑树的平衡
5. 红黑树的子树旋转
6. 右旋转
7. 左旋转
8. 旋转、搜索和插入的演示代码示例


参考

  1. 红黑树-维基百科
  2. 开源代码-GitHub
  3. 二叉搜索树(附 Java 代码)
  4. 数据结构算法解析:红黑树

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

如何在 Java 中延迟几秒钟的时间

发布时间:2023/12/17 浏览次数:217 分类:Java

本篇文章主要介绍如何在 Java 中制造程序延迟。本教程介绍了如何在 Java 中制造程序延时,并列举了一些示例代码来了解它。

如何在 Java 中把 Hashmap 转换为 JSON 对象

发布时间:2023/12/17 浏览次数:187 分类:Java

它描述了允许我们将哈希图转换为简单的 JSON 对象的方法。本文介绍了在 Java 中把 Hashmap 转换为 JSON 对象的方法。我们将看到关于创建一个 hashmap,然后将其转换为 JSON 对象的详细例子。

如何在 Java 中按值排序 Map

发布时间:2023/12/17 浏览次数:171 分类:Java

本文介绍了如何在 Java 中按值对 Map 进行排序。本教程介绍了如何在 Java 中按值对 Map 进行排序,并列出了一些示例代码来理解它。

如何在 Java 中打印 HashMap

发布时间:2023/12/17 浏览次数:192 分类:Java

本帖介绍了如何在 Java 中打印 HashMap。本教程介绍了如何在 Java 中打印 HashMap 元素,还列举了一些示例代码来理解这个主题。

在 Java 中更新 Hashmap 的值

发布时间:2023/12/17 浏览次数:146 分类:Java

本文介绍了如何在 Java 中更新 HashMap 中的一个值。本文介绍了如何在 Java 中使用 HashMap 类中包含的两个方法-put() 和 replace() 更新 HashMap 中的值。

Java 中的 hashmap 和 map 之间的区别

发布时间:2023/12/17 浏览次数:79 分类:Java

本文介绍了 Java 中的 hashmap 和 map 接口之间的区别。本教程介绍了 Java 中 Map 和 HashMap 之间的主要区别。在 Java 中,Map 是用于以键值对存储数据的接口,

在 Java 中获取用户主目录

发布时间:2023/12/17 浏览次数:218 分类:Java

这篇文章向你展示了如何在 Java 中获取用户主目录。本教程介绍了如何在 Java 中获取用户主目录,并列出了一些示例代码以指导你完成该主题。

Java 中 size 和 length 的区别

发布时间:2023/12/17 浏览次数:179 分类:Java

这篇文章教你如何知道 Java 中大小和长度之间的区别。本教程介绍了 Java 中大小和长度之间的区别。我们还列出了一些示例代码以帮助你理解该主题。

Java 中的互斥锁

发布时间:2023/12/17 浏览次数:111 分类:Java

了解有关 Java 中互斥锁的一切,在计算机科学领域,互斥或互斥被称为并发控制的属性。每台计算机都使用称为线程的最小程序指令序列。有一次,计算机在一个线程上工作。为了更好地理解,

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便