红黑树和平衡二叉树有什么区别?「建议收藏」

红黑树和平衡二叉树有什么区别?「建议收藏」什么是二叉树?二叉树(BinaryTree)是指每个节点最多只有两个分支的树结构,即不存在分支大于2的节点,二叉树的数据结构如下图所示这是一棵拥有6个节点深度为2(深度从0开始),并且根节点为3的二叉树二叉树有两个分支通常被称作“左子树”和“右子树”,而且这些分支具有左右次序不能随意地颠倒一棵空树或者满足以下性质的二叉树被称之为二叉查找树若任意节点的左子树不为空,则左子树上所有节点的值均小于它的根节点的值; 若任意节点的右子树不为空,则右子树上所有节点的值均大

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

什么是二叉树?

二叉树(Binary Tree)是指每个节点最多只有两个分支的树结构,即不存在分支大于 2 的节点,二叉树的数据结构如下图所示

红黑树和平衡二叉树有什么区别?「建议收藏」

这是一棵拥有 6 个节点深度为 2(深度从 0 开始),并且根节点为 3 的二叉树

二叉树有两个分支通常被称作“左子树”和“右子树”,而且这些分支具有左右次序不能随意地颠倒

一棵空树或者满足以下性质的二叉树被称之为二叉查找树

  • 若任意节点的左子树不为空,则左子树上所有节点的值均小于它的根节点的值;
  • 若任意节点的右子树不为空,则右子树上所有节点的值均大于或等于它的根节点的值;
  • 任意节点的左、右子树分别为二叉查找树

如下图所示,这就是一个标准的二叉查找树

红黑树和平衡二叉树有什么区别?「建议收藏」

二叉查找树(Binary Search Tree)也被称为二叉搜索树、有序二叉树(Ordered Binary Tree)或排序二叉树(Sorted Binary Tree)等

什么是红黑树?

红黑树(Red Black Tree)是一种自平衡二叉查找树,它最早被称之为“对称二叉 B 树”,它现在的名字源于 1978 年的一篇论文,之后便被称之为红黑树了

所谓的平衡树是指一种改进的二叉查找树,顾名思义平衡树就是将二叉查找树平衡均匀地分布,这样的好处就是可以减少二叉查找树的深度

一般情况下二叉查找树的查询复杂度取决于目标节点到树根的距离(即深度),当节点的深度普遍较大时,查询的平均复杂度就会上升,因此为了实现更高效的查询就有了平衡树

非平衡二叉树如下图所示

红黑树和平衡二叉树有什么区别?「建议收藏」

平衡二叉树如下图所示

红黑树和平衡二叉树有什么区别?「建议收藏」

可以看出使用平衡二叉树可以有效的减少二叉树的深度,从而提高了查询的效率

红黑树除了具备二叉查找树的基本特性之外,还具备以下特性

  • 节点是红色或黑色;
  • 根节点是黑色;
  • 所有叶子都是黑色的空节点(NIL 节点);
  • 每个红色节点必须有两个黑色的子节点,也就是说从每个叶子到根的所有路径上,不能有两个连续的红色节点;
  • 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑色节点

红黑树结构如下图所示

红黑树和平衡二叉树有什么区别?「建议收藏」

红黑树的优势

红黑树的优势在于它是一个平衡二叉查找树,对于普通的二叉查找树(非平衡二叉查找树)在极端情况下可能会退化为链表的结构,例如,当我们依次插入 3、4、5、6、7、8 这些数据时,二叉树会退化为如下链表结构

红黑树和平衡二叉树有什么区别?「建议收藏」

当二叉查找树退化为链表数据结构后,再进行元素的添加、删除以及查询时,它的时间复杂度就会退化为 O(n);而如果使用红黑树的话,它就会将以上数据转化为平衡二叉查找树,这样就可以更加高效的添加、删除以及查询数据了,这就是红黑树的优势

注意:红黑树的高度近似 log2n,它的添加、删除以及查询数据的时间复杂度为 O(logn)

在表示算法的执行时间时,通常会使用大 O 表示法,常见的标识类型有以下这些:

  • O(1):常量时间,计算时间与数据量大小没关系;
  • O(n):计算时间与数据量成线性正比关系;
  • O(logn):计算时间与数据量成对数关系;

自平衡的红黑树

红黑树能够实现自平衡和保持红黑树特征的主要手段是:变色、左旋和右旋

左旋指的是围绕某个节点向左旋转,也就是逆时针旋转某个节点,使得父节点被自己的右子节点所替代,如下图所示

红黑树和平衡二叉树有什么区别?「建议收藏」

在 TreeMap 源码中左旋的实现源码如下

// 源码基于 JDK 1.8
private void rotateLeft(Entry<K,V> p) {
    if (p != null) {
        // 右子节点
        Entry<K,V> r = p.right; 
        // p 节点的右子节点为 r 的左子节点
        p.right = r.left;
        // r 左子节点如果非空,r 左子节点的父节点设置为 p 节点
        if (r.left != null) 
            r.left.parent = p; 
        r.parent = p.parent; // r 父节点等于 p 父节点
        // p 父节点如果为空,那么讲根节点设置为 r 节点
        if (p.parent == null)
            root = r;
        // p 父节点的左子节点如果等于 p 节点,那么 p 父节点的左子节点设置 r 节点
        else if (p.parent.left == p)
            p.parent.left = r;
        else
            p.parent.right = r;
        r.left = p; 
        p.parent = r;
    }
}

左旋代码说明:在刚开始时,p 为父节点,r 为子节点,在左旋操作后,r 节点代替 p 节点的位置,p 节点成为 r 节点的左孩子,而 r 节点的左孩子成为 p 节点的右孩子

右旋指的是围绕某个节点向右旋转,也就是顺时针旋转某个节点,此时父节点会被自己的左子节点取代,如下图所示

红黑树和平衡二叉树有什么区别?「建议收藏」

在 TreeMap 源码中右旋的实现源码如下

private void rotateRight(Entry<K,V> p) {
    if (p != null) {
        Entry<K,V> l = p.left;
        // p 节点的左子节点为 l 的右子节点
        p.left = l.right;
        // l 节点的右子节点非空时,设置 l 的右子节点的父节点为 p
        if (l.right != null) l.right.parent = p;
        l.parent = p.parent;
        // p 节点的父节点为空时,根节点设置成 l 节点
        if (p.parent == null)
            root = l;
        // p 节点的父节点的右子节点等于 p 节点时,p 的父节点的右子节点设置为 l
        else if (p.parent.right == p)
            p.parent.right = l;
        else p.parent.left = l;
        l.right = p;
        p.parent = l;
    }
}

右旋代码说明:在刚开始时,p 为父节点 l 为子节点,在右旋操作后,l 节点代替 p 节点,p 节点成为 l 节点的右孩子,l 节点的右孩子成为 p 节点的左孩子

对于红黑树来说,如果当前节点的左、右子节点均为红色时,因为需要满足红黑树定义的第四条特征,所以需要执行变色操作,如下图所

红黑树和平衡二叉树有什么区别?「建议收藏」

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

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/189485.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • linux搭建git服务端_linux搭建git服务端

    linux搭建git服务端_linux搭建git服务端1、添加git用户useradd-mgit2、修改git用户密码(密码为git)passwdgit3、解压git-1.7.12.2.tar.gz并安装gittar-xvfgit-1.7.12.2.tar.gzcdgit-1.7.12.2makemakeinstall4、初始化一下git用户,为了安装gitosis做准备。在任何一台机器上使用git,第一次必须要初始化一…

  • c比python快多少倍_python和c++哪个简单

    c比python快多少倍_python和c++哪个简单国外有测试指出在相同复杂度算法中,C++约比Python快50倍左右。因此Python适合上层应用;C++则适合底层控制。本文介绍如何让C++和Python形成优势互补

  • redis cluster原理详解_redis cluster原理

    redis cluster原理详解_redis cluster原理本文转载自:https://zhuanlan.zhihu.com/p/69800024RedisCluster是Redis官方提供的集群解决方案。由于业务的飞速增长,单机模式总会遇到内存、性能等各种瓶颈,这个时候我们总会喊,上集群啊。就跟我家热得快炸了,你总喊开空调呀一样。的确,上集群可以解决大多数问题,但是在使用集群的过程中,不可避免会遇到这样那样的问题,这个时候怎么办呢,各种百度各种群里去问吗?NO,作为开发人员,在享受第三方提供的方便前,有必要去了解其基本的工作机制,这样才能在遇到问题时快速定位,

    2022年10月14日
  • 开发环境、测试环境、生产环境、UAT环境、仿真环境详解「建议收藏」

    开发环境、测试环境、生产环境、UAT环境、仿真环境详解「建议收藏」开发环境(DEV):开发环境是程序猿们专门用于开发的服务器,配置可以比较随意,为了开发调试方便,一般打开全部错误报告。测试环境(UAT):一般是克隆一份生产环境的配置,一个程序在测试环境工作不正常,那么肯定不能把它发布到生产机上。生产环境(PROD):是指正式提供对外服务的,一般会关掉错误报告,打开错误日志。可以理解为包含所有的功能的环境,任何项目所使用的环境都以这个为基础,然后根据客户…

  • silverlight开发教程_手机安装silverlight插件

    silverlight开发教程_手机安装silverlight插件教程地址:http://kb.cnblogs.com/zt/silverlight/

  • MATLAB GUI实现计算器(设计)「建议收藏」

    MATLAB GUI实现计算器(设计)「建议收藏」1.先打开matlab新建GUI文件2.选择路径(左边是默认的不用改)然后点击ok3.此时界面会弹出一个小框4.建立计算器界面(贴上我设计的界面,不许嘲笑我的设计)5.细致讲解一下,这里的按键和显示框的是怎么实现的A.显示框:选择edittext在右边屏幕拉取即可如图所示,新建两个即可,左边作为输入屏,右边作为输入结果的显示屏双击该框,…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号