Java二叉树和红黑树

简介: Java二叉树和红黑树

笔者会据需补充二叉树的相关一系列知识,先更新最基本的二叉树的知识.


1 二叉树

二叉树的特点


二叉树中,任意一个节点的度要小于等于2


节点: 在树结构中,每一个元素称之为节点


度: 每一个节点的子节点数量称之为度


左子节点 右子节点 值 父节点 定义时一个节点四个变量


二叉树结构图


2020092723124057.png


2 二叉查找树

二叉查找树的特点


二叉查找树,又称二叉排序树或者二叉搜索树


每一个节点上最多有两个子节点


左子树上所有节点的值都小于根节点的值


右子树上所有节点的值都大于根节点的值


二叉查找树结构图


20200927231324608.png


二叉查找树和二叉树对比结构图

20200927231349933.png


二叉查找树添加节点规则


小的存左边

大的存右边

一样的不存

20200927231427171.png


3 平衡二叉树

平衡二叉树的特点


二叉树左右两个子树的高度差不超过1


任意节点的左右两个子树都是一颗平衡二叉树


平衡二叉树旋转


旋转触发时机


当添加一个节点之后,该树不再是一颗平衡二叉树也就是说原来是一颗平衡的添加后不平衡的过程,重复不添加


左旋


就是将根节点的右侧往左拉,原先的右子节点变成新的父节点,并把多余的左子节点出让,给已经降级的根节点当右子节点


20200927231535240.png

20200927231444614.png



右旋


就是将根节点的左侧往右拉,左子节点变成了新的父节点,并把多余的右子节点出让,给已经降级根节点当左子节点

20200927231552649.png


20200927231600772.png



平衡二叉树和二叉查找树对比结构图


20200927231623975.png


平衡二叉树旋转的四种情况


左左


左左: 当根节点左子树的左子树有节点插入,导致二叉树不平衡


如何旋转: 直接对整体进行右旋即可


20200927232109166.png


左右


左右: 当根节点左子树的右子树有节点插入,导致二叉树不平衡


如何旋转: 先在左子树对应的节点位置进行左旋,在对整体进行右旋


20200927232242528.png


右右


右右: 当根节点右子树的右子树有节点插入,导致二叉树不平衡


如何旋转: 直接对整体进行左旋即可


20200927232300616.png


右左


右左:当根节点右子树的左子树有节点插入,导致二叉树不平衡


如何旋转: 先在右子树对应的节点位置进行右旋,在对整体进行左旋


20200927232317999.png


4 红黑树

红黑树的特点


平衡二叉B树 特殊的二叉排序树


每一个节点可以是红或者黑


红黑树不是高度平衡的,它的平衡是通过"自己的红黑规则"进行实现的


红黑树的红黑规则有哪些


每一个节点或是红色的,或者是黑色的


根节点必须是黑色


如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的


如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连 的情况)


对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点

2020093019072837.png



红黑树添加节点的默认颜色


添加节点时,默认为红色,效率高



20200930190747173.png



红黑树添加节点后如何保持红黑规则

20200930194554955.png



jdk源码:


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)))) {
                Entry<K,V> y = rightOf(parentOf(parentOf(x)));
                if (colorOf(y) == RED) {
                    setColor(parentOf(x), BLACK);
                    setColor(y, BLACK);
                    setColor(parentOf(parentOf(x)), RED);
                    x = parentOf(parentOf(x));
                } else {
                    if (x == rightOf(parentOf(x))) {
                        x = parentOf(x);
                        rotateLeft(x);
                    }
                    setColor(parentOf(x), BLACK);
                    setColor(parentOf(parentOf(x)), RED);
                    rotateRight(parentOf(parentOf(x)));
                }
            } else {
                Entry<K,V> y = leftOf(parentOf(parentOf(x)));
                if (colorOf(y) == RED) {
                    setColor(parentOf(x), BLACK);
                    setColor(y, BLACK);
                    setColor(parentOf(parentOf(x)), RED);
                    x = parentOf(parentOf(x));
                } else {
                    if (x == leftOf(parentOf(x))) {
                        x = parentOf(x);
                        rotateRight(x);
                    }
                    setColor(parentOf(x), BLACK);
                    setColor(parentOf(parentOf(x)), RED);
                    rotateLeft(parentOf(parentOf(x)));
                }
            }
        }
        root.color = BLACK;
    }


解析:


20200930191627199.png


简单的理解


在有爷爷为根的情况:


20200930194656377.png


左左情况


这种情况很简单,想象这是一根绳子,手提起 P 节点,然后变色即可


20200930191844197.png


左右


左旋: 使 X 的父节点 P 被 X 取代,同时父节点 P 成为 X 的左孩子,然后再应用 左左情况


20200930191854566.png


右右


与左左情况一样,想象成一根绳子

20200930191904426.png



右左

右旋: 使 X 的父节点 P 被 X 取代,同时父节点 P 成为 X 的右孩子,然后再应用 右右情况

目录
相关文章
|
算法 Java
JAVA 二叉树面试题
JAVA 二叉树面试题
86 0
|
Java 开发者
在Java的集合世界里,Set以其独特的特性脱颖而出,它通过“哈希魔法”和“红黑树防御”两大绝技
【10月更文挑战第13天】在Java的集合世界里,Set以其独特的特性脱颖而出。它通过“哈希魔法”和“红黑树防御”两大绝技,有效抵御重复元素的侵扰,确保集合的纯洁性和有序性。无论是“人海战术”还是“偷梁换柱”,Set都能从容应对,成为开发者手中不可或缺的利器。
107 6
|
Java
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
126 1
|
算法 Java C语言
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
101 1
|
存储 开发者 C#
WPF与邮件发送:教你如何在Windows Presentation Foundation应用中无缝集成电子邮件功能——从界面设计到代码实现,全面解析邮件发送的每一个细节密武器!
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中集成电子邮件发送功能,详细介绍了从创建WPF项目到设计用户界面的全过程,并通过具体示例代码展示了如何使用`System.Net.Mail`命名空间中的`SmtpClient`和`MailMessage`类来实现邮件发送逻辑。文章还强调了安全性和错误处理的重要性,提供了实用的异常捕获代码片段,旨在帮助WPF开发者更好地掌握邮件发送技术,提升应用程序的功能性与用户体验。
315 0
|
存储 Java 开发者
揭秘!HashMap底层结构大起底:从数组到链表,再到红黑树,Java性能优化的秘密武器!
【8月更文挑战第24天】HashMap是Java集合框架中的核心组件,以其高效的键值对存储和快速访问能力广受开发者欢迎。在JDK 1.8及以后版本中,HashMap采用了数组+链表+红黑树的混合结构,实现了高性能的同时解决了哈希冲突问题。数组作为基石确保了快速定位;链表则用于处理哈希冲突;而当链表长度达到一定阈值时,通过转换为红黑树进一步提升性能。此外,HashMap还具备动态扩容机制,当负载因子超过预设值时自动扩大容量并重新哈希,确保整体性能。通过对HashMap底层结构的深入了解,我们可以更好地利用其优势解决实际开发中的问题。
340 0
【Java集合类面试十一】、HashMap为什么用红黑树而不用B树?
HashMap选择使用红黑树而非B树,是因为红黑树在内存中实现简单,节点更小,占用内存少,且在插入、删除和查找操作上提供更好的平衡性能。
|
存储 算法 Java
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
216 0
二叉树简单遍历、查找、删除(java)
二叉树简单遍历、查找、删除(java)
|
存储 Java
顺序存储二叉树(java)
顺序存储二叉树(java)