广告
返回顶部
首页 > 资讯 > 精选 >Java数据结构之红黑树的示例分析
  • 906
分享到

Java数据结构之红黑树的示例分析

java 2023-05-30 22:05:15 906人浏览 安东尼
摘要

小编给大家分享一下Java数据结构之红黑树的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、红黑树所处数据结构的位置:在jdk源码中, 有treeMap

小编给大家分享一下Java数据结构之红黑树的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

一、红黑树所处数据结构的位置:

jdk源码中, 有treeMap和JDK8的HashMap都用到了红黑树去存储

红黑树可以看成B树的一种:

二叉树看,红黑树是一颗相对平衡的二叉树

二叉树-->搜索二叉树-->平衡搜索二叉树--> 红黑树

从N阶树看,红黑树就是一颗 2-3-4树

N阶树-->B(B-)树

 故我提取出了红黑树部分的源码,去说明红黑树的理解

看之前,理解红黑树的几个特性,后面的操作都是为了让树符合红黑树的这几个特性,从而满足对查找效率的O(logn)

二、红黑树特性,以及保持的手段

根和叶子节点都是黑色的

不能有有连续两个红色的节点

从任一节点到它所能到达得叶子节点的所有简单路径都包含相同数目的黑色节点 

这几个特效,个人理解就是规定了红黑树是一颗2-3-4的B树了,从而满足了O(logn)查找效率 

保持特性的手段,通过下面这些手段,让红黑树满足红黑树的特性,如果要尝试理解,可以从2-3-4树的向上增长,后面有详细介绍 

当然,这些改变也都是在O(logn)内完成的,主要改变方式有

改变颜色

左旋

右旋 

三、从JDK源码来理解

主要看我的注释,逻辑的理解

先看TreeMap

//对treeMap的红黑树理解注解. 2017.02.16 by 何锦彬 JDK,1.7.51<br> <br> private void fixAfterInsertion(Entry<K, V> x) {         //新加入红黑树的默认节点就是红色  x.color = RED;    while (x != null && x != root && x.parent.color == RED) {       if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {         //如果X的父节点(P)是其父节点的父节点(G)的左节点    //即 下面这种情况            //获取其叔(U)节点    Entry<K, V> y = rightOf(parentOf(parentOf(x)));    if (colorOf(y) == RED) {     // 这种情况,对应下面 图:情况一          //如果叔节点是红色的(父节点有判断是红色). 即是双红色,比较好办,通过改变颜色就行. 把P和U都设置成黑色然后,X加到P节点。 G节点当作新加入节点继续迭代     setColor(parentOf(x), BLACK);     setColor(y, BLACK);     setColor(parentOf(parentOf(x)), RED);     x = parentOf(parentOf(x));    } else {     //处理红父,黑叔的情况     if (x == rightOf(parentOf(x))) {      // 这种情况,对应下面 图:情况二            //如果X是右边节点      x = parentOf(x);      // 进行左旋      rotateLeft(x);     }     //左旋后,是这种情况了,对应下面 图:情况三                // 到这,X只能是左节点了,而且P是红色,U是黑色的情况     //把P改成黑色,G改成红色,以G为节点进行右旋     setColor(parentOf(x), BLACK);     setColor(parentOf(parentOf(x)), RED);     rotateRight(parentOf(parentOf(x)));    }   } else {    //父节点在右边的            //获取U    Entry<K, V> y = leftOf(parentOf(parentOf(x)));         if (colorOf(y) == RED) {     //红父红叔的情况           setColor(parentOf(x), BLACK);     setColor(y, BLACK);     setColor(parentOf(parentOf(x)), RED);     //把G当作新插入的节点继续进行迭代     x = parentOf(parentOf(x));    } else {     //红父黑叔,并且是右父的情况           if (x == leftOf(parentOf(x))) {     //如果插入的X是左节点            x = parentOf(x);      //以P为节点进行右旋      rotateRight(x);     }     //右旋后          setColor(parentOf(x), BLACK);     setColor(parentOf(parentOf(x)), RED);     //以G为节点进行左旋     rotateLeft(parentOf(parentOf(x)));    }   }  }  //红黑树的根节点始终是黑色  root.color = BLACK; }

再看看HashMap的实现,在HashMap中,在JDK8后开始用红黑树代替链表,查找由O(n) 变成了 O(Logn)

源码分析如下:

for (int binCount = 0; ; ++binCount) {     if ((e = p.next) == null) {      p.next = newnode(hash, key, value, null);      //JDK8 的hashmap,链表到了8就需要变成颗红黑树了      if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st       treeifyBin(tab, hash);      break;     }

红黑树的维护代码部分如下:

//hashmap的红黑树平衡   static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root,               TreeNode<K,V> x) {     x.red = true;     //死循环加变量定义,总感觉JAVA很少这样写代码 哈     for (TreeNode<K,V> xp, xpp, xppl, xppr;;) {      //xp X父节点, XPP X的祖父节点, XPPL 祖父左节点 XXPR 祖父右节点       if ((xp = x.parent) == null) {       x.red = false;       return x;      }      // 如果父节点是黑色, 或者XP父节点是空,直接返回      else if (!xp.red || (xpp = xp.parent) == null)       return root;            // 下面的代码就和上面的很treeMap像了,            if (xp == (xppl = xpp.left)) {        // 第一种情况, 赋值xppl       //父节点是左节点的情况,下面这种                  if ((xppr = xpp.right) != null && xppr.red) {        //如果红叔的情况         // 这种情况,对应下面 图:情况一                 //改变其颜色,        xppr.red = false;        xp.red = false;        xpp.red = true;        x = xpp;       }       else {         // 黑叔的情况        // 这种情况                if (x == xp.right) {         //如果插入节点在右边 这种          // 这种情况,对应下面 图:情况二                  //需要进行左旋         root = rotateLeft(root, x = xp);         xpp = (xp = x.parent) == null ? null : xp.parent;        }        //左旋后情况都是这种了,对应下面 图:情况三                // 到这,X只能是左节点了,而且P是红色,U是黑色的情况        if (xp != null) {        //把P改成黑色,G改成红色, 以G为节点进行右旋         xp.red = false;         if (xpp != null) {          xpp.red = true;          root = rotateRight(root, xpp);         }        }       }      }      else {        //父节点在右边的                  //获取U       if (xppl != null && xppl.red) {        //红父红叔的情况                     xppl.red = false;        xp.red = false;        xpp.red = true;        x = xpp;       }       else {                if (x == xp.left) {         //如果插入的X是右节点                  root = rotateRight(root, x = xp);         xpp = (xp = x.parent) == null ? null : xp.parent;        }        //右旋后                if (xp != null) {         //把P改成黑色,G改成红色,         xp.red = false;         if (xpp != null) {          xpp.red = true;          //以G节点左旋          root = rotateLeft(root, xpp);         }        }       }      } }

情况图如下

Java数据结构之红黑树的示例分析

情况1

Java数据结构之红黑树的示例分析

情况2

Java数据结构之红黑树的示例分析

情况3

JDK源码处理红黑树的流程图

Java数据结构之红黑树的示例分析

可见,其实处理逻辑实现都一样的

三、个人对红黑树理解的方法

如何理解红黑树的O(lgN)的特性?

从2-3-4树去理解

红黑树,其实是一颗 2-3-4的B树,B树都是向上增长的,如果不理解向上增长可以先看看2-3树,这样理解就能知道为什么能O(logn)的查找了

如何理解红黑树的红黑节点意义?

可以把红色节点看成是连接父节点的组成的一个大节点(2个或3个或4个节点组成的一个key),如下:

Java数据结构之红黑树的示例分析

(此图转自网上)

红色的就是和父节点组成了大节点,

比如

节点7和6,6是红色节点组成,故和它父节点7组成了一个大节点,即 2-3-4树的 6, 7节点

又如

节点 9和10和11,9和10为红色节点,故和10组成了一个2-3-4的3阶节点, 9,10,11(注意顺序有的关性)

B树是如何保持O(lgn)的复杂度的呢?

B+树都是从底布开始往上生长,自动平衡,如 2-3-4树,当节点达到了3个时晋升到上个节点,所以不会产生单独生长一边的情况,形成平衡。

以上是“Java数据结构之红黑树的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: Java数据结构之红黑树的示例分析

本文链接: https://www.lsjlt.com/news/221917.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java数据结构之红黑树的示例分析
    小编给大家分享一下Java数据结构之红黑树的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、红黑树所处数据结构的位置:在JDK源码中, 有treeMap...
    99+
    2023-05-30
    java
  • C++数据结构红黑树的示例分析
    这篇文章给大家分享的是有关C++数据结构红黑树的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。概念和性质红黑树的概念: 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或...
    99+
    2023-06-29
  • java数据结构之树的示例分析
    这篇文章主要介绍java数据结构之树的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!树定义和基本术语定义树(Tree)是n(n≥0)个结点的有限集T,并且当n>0时满足下列条件:(1)有且仅有一个特定的称为根...
    99+
    2023-05-30
    java
  • C++数据结构红黑树全面分析
    目录概念和性质红黑树的实现红黑树节点定义红黑树结构定义红黑树的插入方法概述调整节点颜色插入代码实现红黑树的删除方法概述调整颜色删除代码实现红黑树的查找红黑树的验证AVL树和红黑树的比...
    99+
    2022-11-13
  • Java红黑树的数据结构与算法解析
    目录红黑树的介绍红黑树的实现1.节点2.查找3.平衡化颜色反转 插入的实现红黑树的复杂度–总结红黑树的介绍 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的...
    99+
    2022-11-12
  • C++数据结构之红黑树的实现
    目录一、什么是红黑树二、红黑树的约定三、红黑树vsAVL四、红黑树的实现1.找到插入的位置2.控制平衡3.测试代码五、完整代码1.test.c2.RBTree.h一、什么是红黑树 红...
    99+
    2022-11-13
    C++ 数据结构 红黑树 C++ 红黑树
  • Java数据结构之红黑树的原理及实现
    目录为什么要有红黑树这种数据结构红黑树的简介红黑树的基本操作之旋转红黑树之添加元素红黑树之删除结点删除结点没有儿子的情况删除结点仅有一个儿子结点的情况删除结点有两个儿子结点红黑树动态...
    99+
    2022-11-13
  • C++中红黑树的示例分析
    这篇文章将为大家详细讲解有关C++中红黑树的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。红黑树红黑树的概念红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以...
    99+
    2023-06-29
  • Java数据结构之AVL树实例分析
    这篇文章主要介绍“Java数据结构之AVL树实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java数据结构之AVL树实例分析”文章能帮助大家解决问题。AVL树的引入搜索二叉树有着极高的搜索效...
    99+
    2023-06-30
  • JavaScript之树结构的示例分析
    这篇文章主要介绍了JavaScript之树结构的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。二叉树--概念--二叉树是一种树形结构...
    99+
    2022-10-19
  • Java数据结构与算法系列精讲之红黑树
    目录概述红黑树红黑树的实现Node 类添加元素左旋右旋完整代码概述 从今天开始, 小白我将带大家开启 Java 数据结构 & 算法的新篇章. 红黑树 红黑树 (Red Bl...
    99+
    2022-11-13
  • Java数据结构之实现哈夫曼树的示例分析
    这篇文章主要介绍了Java数据结构之实现哈夫曼树的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、与哈夫曼树相关的概念概念含义1. 路径从树中一个结点到另一个结点的...
    99+
    2023-06-15
  • ConcurrentHashMap: 红黑树代理类的示例分析
    小编给大家分享一下ConcurrentHashMap: 红黑树代理类的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、TreeBin内部类分析TreeB...
    99+
    2023-06-15
  • Java数据结构之链表的示例分析
    小编给大家分享一下Java数据结构之链表的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、链表的介绍什么是链表链表是一种物理存储单元上非连续、非顺序的存...
    99+
    2023-06-15
  • Java数据结构之二叉搜索树实例分析
    这篇文章主要介绍“Java数据结构之二叉搜索树实例分析”,在日常操作中,相信很多人在Java数据结构之二叉搜索树实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java数据结构之二叉搜索树实例分析”的疑...
    99+
    2023-06-30
  • javascript数据结构之多叉树经典操作的示例分析
    这篇文章给大家分享的是有关javascript数据结构之多叉树经典操作的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。多叉树可以实现复杂的数据结构的存储,通过遍历方法可以...
    99+
    2022-10-19
  • Java中数据结构的示例分析
    这篇文章将为大家详细讲解有关Java中数据结构的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.1.1.       增量内存分配 ArrayList 、 Hash...
    99+
    2023-06-03
  • PHP数据结构之图存储结构的示例分析
    这篇文章主要介绍PHP数据结构之图存储结构的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!图的存储结构图的概念介绍得差不多了,大家可以消化消化再继续学习后面的内容。如果没有什么问题的话,我们就继续学习接下来的...
    99+
    2023-06-20
  • java数据结构之二分查找法binarySearch的示例分析
    这篇文章给大家分享的是有关java数据结构之二分查找法binarySearch的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。java数据结构之二分查找法 binarySearch的实例折半查找法,前提是...
    99+
    2023-05-31
    java
  • Java数据结构和算法之链表的示例分析
    这篇文章主要介绍Java数据结构和算法之链表的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、链表(Linked List)链表通常由一连串节点组成,每个节点包含任意的实例数据(data fiel...
    99+
    2023-06-28
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作