01基础-算法第四版红黑树-红黑树-数据结构和算法(Java)

news/2024/11/25 3:44:27/

文章目录

    • 1 前言
    • 2 定义
      • 2.1 替换3-结点
      • 2.2 等价定义
      • 2.3 一一对应
    • 3 基础
      • 3.1 颜色表示
      • 3.2 结点表示
      • 3.2 旋转
      • 3.3 旋转后重置父结点的链接
    • 后记

1 前言

目前我学习到的2种红黑树:一种是红黑树的标准定义,另外一种是《算法第4版》中的红黑树。后一种定义只比前一种多了一个条件:红链接均为左链接(红色结点均为左子结点)。

关于对红黑树的理解,可以把它当做前面我们学习的2-3树的一种特殊形式,按照2-3树的思想来学习理解。那如果之前没有接触过2-3树呢?拿就把它当做一种新的二叉树结构来学习就好,没必要纠结这个。只要最终我们实现它的基本操作,且操作完成后它依然符合红黑树的性质(定义)就好。

我们先来讲解第二种定义的红黑树,按2-3树来理解,主要参考《算法第4版》;后面会以一种新的二叉树的视角来讲解第一种红黑树,主要参考JDK8+ 的HashMap中的红黑树。最后,我们会对这两种方式做对比。

2 定义

2.1 替换3-结点

红黑二叉查找树基本思想是用标准的二叉查找树(完全由2-结点构成)和一些额外的信息(替换3-结点)来表示2-3树。我们把树中的链接分为2中类型:红链接将两个2-结点连接起来构成一个3-结点,黑链接则是2-3树中的普通链接。确切的说我们将3-结点表示为一条左斜的红色链接(两个2-结点其中之一是另外一个的左子结点)相连的两个2-结点。

2.2 等价定义

红黑树的另外一种定义是含义红黑树链接并满足下列条件的二叉查找树:

  • 红链接均为左链接
  • 没有任何一个结点同时和两条红色链接相连;
  • 该树是完美黑色平衡的,即任意空链接到根结点的路径上的黑链接数量相同。

满足这样定义的红黑树和相应的2-3树是一一对应的。

2.3 一一对应

如果将一棵红黑树中的红链接画平,那么所有的空链接到根结点的距离都将是相同的。如果我们将由红链接相连的的结点合并,得到的就是一棵2-3树。相反,如果一棵2-3树中的3-结点画作由红链接链接的2-结点,那么不会存在能够和两条红链接链接的结点,且树必然是完美黑色平衡的,因为黑链接即2-3树中的普通链接,根据定义这些链接必然是完美平衡的,如下图所示:在这里插入图片描述

因此,如果我们能够在保持一一对应关系的基础上实现2-3树的插入算法,那么我们就能够将两个算法的有的结合起来:二叉查找树中简洁高效的查找方法和2-3树中高效的平衡插入算法。

3 基础

3.1 颜色表示

方便起见,因为每个结点都只会有一条指向自己的链接(从它的父结点指向它),我们将结点的颜色保存在表示结点的Node数据类型的布尔变量color中。如果指向它的链接是红色的,那么该变量为true,黑色则表示false。我们约定空链接为黑色。为了代码的清晰,定义了2个常量RED和BLACK来设置和测试这个变量。我们使用私有方法isRed()来测试一个结点和它的父结点之间链接的颜色。isRed源代码如下:

/*** 链接(结点)颜色 RED = true表示红链接;BLACK = false表示黑链接*/
private static final boolean RED = true;
private static final boolean BLACK = false;
/*** 判断当前结点和父链接是否为红色* @param x 当前结点* @return  当前结点不为空且当前结点color属性为RED,返回{@code true};否则返回{@code false}*/
private boolean isRed(Node x) { return x != null && x.color == RED;}

3.2 结点表示

/*** 结点类*/
class Node {/*** 键*/K key;/*** 值*/V value;/*** 左右链接(子结点)*/Node left, right;/*** 子树结点个数*/int n;/*** 链接颜色*/boolean color;public Node(K key, V value, Node left, Node right) {this.key = key;this.value = value;this.left = left;this.right = right;// 默认新建结点为根结点的子树结点个数为1this.n = 1;// 默认新建结点颜色为红色this.color = RED;}public Node(K key, V value) {this(key, value, null, null);}
}

3.2 旋转

在我们实现的某些操作中可能会出现红色链接或者两条连续的红链接,但在操作完成之前这些情况都会被小心地旋转并修复。选择操作会改变红链接的指向。把一条红色的右链接转化为左链接,称为左旋[转]。如下图所示:

在这里插入图片描述

非递归左旋代码3.2-1实现如下:

/*** 以子树根结点为轴左旋* @param p 子树根结点* @return  左旋完成后的子树根结点*/
private Node rotateLeft(Node p) {// 调整链接Node x = p.right;int n = 1 + (x.right == null ? 0: x.right.n);p.right = x.left;x.left = p;// 调整颜色x.color = p.color;p.color = RED;// 计算结点数x.n = p.n;p.n = x.n - n;return x;
}

把一条红色左链接转化为右链接,称为右旋[转],图示如下:在这里插入图片描述

非递归代码实现代码3.2-2如下:

/*** 以子树根结点为轴右旋* @param p 子树根结点* @return  右旋完成后的子树根结点*/
private Node rotateRight(Node p) {// 调整链接Node x = p.left;int n = 1 + (x.left == null ? 0: x.left.n);p.left = x.right;x.right = p;// 调整颜色x.color = p.color;p.color = RED;// 计算结点数x.n = p.n;p.n = x.n - n;return x;
}

3.3 旋转后重置父结点的链接

无论是左旋还是右旋,操作完成后返回一条链接,我们会把它赋予父结点中链接,可能是红色也可能是黑色。这可能产生两条连续的红链接,我们会通过旋转操作修正。

后续讲解插入、删除、有序性想关操作等。

后记

​ 如果小伙伴什么问题或者指教,欢迎交流。

❓QQ:806797785

⭐️源代码仓库地址:https://gitee.com/gaogzhen/algorithm

[1][美]Robert Sedgewich,[美]Kevin Wayne著;谢路云译.算法:第4版[M].北京:人民邮电出版社,2012.10


http://www.ppmy.cn/news/22822.html

相关文章

新浪l2接口的具体功能有哪些?可以提供哪些数据?

在API接口服务广泛发展的今天,金融行业也有许多API接口的诞生,其中就包括股票行情API,这是一种能够帮助企业实时查询各类股票行情,分析股票市场上各类股票价格走势、涨跌幅度,辅助企业做出投资决策的一种应用程序编程接…

2022年开发踩坑记录

20220106 乐观锁 额外增加字段,时间戳,版本号之类的标志,取数据时要带着版本号 更新数据时,如果库内版本号与传入一致,则更新,否则不更新 悲观锁 查询出要更新的数据,然后加for update &#…

【Ubuntu18.04离线安装网卡驱动】自带r8169安装r8125有线网卡驱动

一、背景 安装Ubuntu18.04.6后 没有网络连接 发现: 有线网卡是8125 而自带的驱动型号为r8169 猜测: 网卡固件型号和驱动版本不匹配 二、尝试 参考了: 有线网卡: https://blog.csdn.net/qq_35097289/article/details/1219969…

论文笔记:Space-time Neural Irradiance Fields for Free-Viewpoint Video

论文标题:自由视角的时空神经辐射(发光)场 创新点 使用RGBD单目视频(2.5D)表示时空。引入对场景深度的监督解决运动模糊问题。 (本文仅介绍对NeRF的改进部分) 深度重建损失 问题&#xff1…

通讯录2.0(动态内存管理)

个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【C/C】 哈喽!今天再次来到通讯录这里,不过是给它进行了一次小小的升级(把动态内存的知识给它嵌入到里…

C# 基础知识(二)_第一个入门程序

目录 C# 基础知识(二)_第一个入门程序 Hello World 代码分析 执行程序 C# 基础知识(二)_第一个入门程序 Hello World using System;namespace Notes {class Program{static void Main(string[] args){//第一个C#程序Console.WriteLine("Hello World!"); …

python GUI(Tkinter)

Tkinter简介 是python内置的标准GUI库,在安装python后,导入模块即可正常使用,Tk和Tkinter可在大多数的Unix,以及Windows和Macintosh系统上运行。 关于Tkinter的导入(注意大小写) 在2.x版本上&#xff0c…

第004天:APP在平板上的UI布局设计

当今是移动设备发展非常迅速的时代,不仅手机已经成为了生活必需品,就连平板电脑也变 得越来越普及。平板电脑和手机最大的区别就在于屏幕的大小,一般手机屏幕的大小会在3英寸 到6英寸之间,而一般平板电脑屏幕的大小会在7英寸到10英…