Java开发 - 树(二叉树,二叉排序树,红黑树)(二)

简介: Java开发 - 树(二叉树,二叉排序树,红黑树)

增加元素


判断root是否为null
  -为null,则将元素封装成节点,称为root,返回true
  -不为null,和root进行比较,比较的目的是将元素尝试添加为root的left/right子树
    - 和root相等,添加失败,返回false,结束
    - 大于>root,尝试添加为root的right;判断right是否为null,
      - 为null,则让新元素封装成节点,称为right,添加成功,返回true
      - 不为null,继续和right的节点进行比较,尝试将元素添加为right的left/right子树
    - 小于,同理

增加元素需要先判断root是否为null


为null,将元素封装成根结点,返回true;

非null,和root进行比较,这是为了判断新元素是添加左子树还是右子树,但不一定添加成功

和root相等,那么添加失败,返回false,结束

大于root,尝试添加为root的右子树,判断right是否为null;

为null,将新元素封装成节点,成为右子树right,添加完成,返回true;

不为null,和right节点进行比较,尝试将该元素添加为right的left/right子树(这里递归就出现了)

小于root,尝试添加为root的左子树,判断left是否为null;

为null,将新元素封装成节点,成为左子树left,添加完成,返回true;

不为null,和left节点进行比较,尝试将该元素添加为left的left/right子树(这里递归就出现了)


思路理清了,那我们就开始写代码:

//添加元素
    public boolean add(E e){
        //判断root是否为null,为null,成为根节点
        if (root==null) {
            root = new Node(e);
            return true;
        }
        //root不为null,添加
        return root.append(e);
    }

Node内的添加方法:

       //向某个节点上添加给定的元素,尝试让新元素称为其左/右子树
        public boolean append(E e) {
            if (e.compareTo(ele) == 0) {
                return false;
            } else if (e.compareTo(ele) < 0) {
                if (left == null) {
                    left = new Node(e);
                    return true;
                }
                return left.append(e);
            } else {
                if (right == null) {
                    right = new Node(e);
                    return true;
                }
                return right.append(e);
            }
        }


查询元素


查询元素也需要先判断root是否为null


为null,树中没有节点,返回null;

非null,判断root节点是否为需要查找的元素

相等,root节点就是需要的元素,返回root节点,结束;

大于ele,就到节点的right去查找相等节点,判断right节点是否存在

为null,说明查询的元素不在此树中,返回null

非null,判断right节点是不是要找的节点,往后一直重复上述操作,直到找到或找不到为止

小于ele,就到节点的left去查找相等节点,判断left节点是否存在

为null,说明查询的元素不在此树中,返回null

非null,判断left节点是不是要找的节点,往后一直重复上述操作,直到找到或找不到为止


用代码来写下这个过程:

    //根据元素查询对应的节点对象
    public Node get(E e){
        //判断root是否为null
        if (root==null)
            return null;
        //root不为空,则判断root是否为目标节点
        return root.isDestNode(e);
    }

Node内的查询:

        //用于判断调用方法的节点是否为目标节点
        public Node isDestNode(E e) {
            //判断e是否和当前节点的元素相等,若相等,说明为目标节点,返回当前节点即可
            if (e.compareTo(ele)==0)
                return this;
            else if (e.compareTo(ele)>0){  //e大于当前节点,到right上继续查找
                //若right为null,说明目标元素不存在树中,返回null
                if (right==null)
                    return null;
                return right.isDestNode(e);
            }else {  //e小于当前节点,到left上继续查找
                if (left==null)
                    return null;
                return left.isDestNode(e);
            }
        }


修改元素


修改其实很简单,首先是查找,查找到之后,直接将新的元素指向那个节点。


我们可以定义这个方法如下:

set(E ele, E newEle)

修改理论上是可行的,但是在修改的时候,会不会引起重新排序呢?这对整个树结构是有影响的,代码似乎也没有刚开始说的那么简单了,重新排序对性能也有影响,所以二叉树可不提供修改方法。


删除元素


这要看删的是谁,如果删除的是叶子结点,那直接删了就好,不需要做什么判断,也不存在排序问题。一旦删除的是中间的节点,看下图:

1.png

假如删的是2或者6,这时候就要考虑谁上去的问题了。


所以删除分为三种情况:


删除叶子结点:将其父节点指向它的引用置为null;

删除有一棵子树的节点:将其父节点的指向变更为被删除的节点的子节点;

删除有两颗子树的节点:让被删除节点的前驱节点或者后继节点上来替换此节点;

前驱节点和后继节点是指升序排列后,删除节点的前一个元素叫做前驱节点,删除节点的后一个元素叫做后继节点

代码写起来会非常复杂,体验很差,所以就不写了,理解了就行,有兴趣的同学可自行尝试。


遍历二叉树


遍历的方式分为三种:

先序遍历:根  左  右

中序遍历:左  根  右

后序遍历:左  右  根


什么意思呢?我们根据一棵树来说:

1.png

先序遍历:4,2,1,3,6,5,7(即先根,后左,再右)

中序遍历:1,2,3,4,5,6,7(即先左,后根,再右,也叫升序排列)

后序遍历:1,3,2,5,7,6 ,4(即先左,后右,再根)


重写toString


目的是为了实现输出引用,将二叉树中的元素遍历,并以此格式输出:[1,2,3,4,5,6,7]输出,没有节点,返回[]。

    //重写toString
    @Override
    public String toString() {
        //判断root是否为null,为null,返回"[]"
        if (root==null)
            return "[]";
        //进行中序遍历
        StringBuilder builder = new StringBuilder("[");
        return root.middleOrder(builder).replace(builder.length()-1,builder.length(),"]").toString();

Node内的方法:

        public StringBuilder middleOrder(StringBuilder builder) {
            //左
            if (left!=null){
                left.middleOrder(builder);
            }
            //取根的值
            builder.append(ele).append(",");
            //取右
            if (right!=null){
                right.middleOrder(builder);
            }
            //以上三步操作结束,得到遍历树后的元素拼接结果,将最后的逗号替换为]
            return builder;
        }

中序遍历这里有个递归,我们要明白的是,最终所有的代码都要取到根的值,这个节点是相对的,每个节点都会是这个根,这样才能拼接出字符串。大家可以动手尝试下其他遍历方式的写法,这里不再赘述。


二叉排序树的极端情况

1.png

这就是失衡二叉树,失衡二叉树是不希望存在的,因为它失去了二叉树本身的优势特点,这种状态和单向链表一样,单向链表的效率如何,想必大家都是知道的。


所以在设计数据结构的时候,已经考虑了这种情况,出现了两种新的数据结构,他们都基于二叉排序树,保留了其优势,又避免了这个缺点。


他们是平衡二叉树和红黑树。

目录
相关文章
|
6天前
|
SQL 安全 Java
安全问题已经成为软件开发中不可忽视的重要议题。对于使用Java语言开发的应用程序来说,安全性更是至关重要
在当今网络环境下,Java应用的安全性至关重要。本文深入探讨了Java安全编程的最佳实践,包括代码审查、输入验证、输出编码、访问控制和加密技术等,帮助开发者构建安全可靠的应用。通过掌握相关技术和工具,开发者可以有效防范安全威胁,确保应用的安全性。
18 4
|
8天前
|
缓存 监控 Java
如何运用JAVA开发API接口?
本文详细介绍了如何使用Java开发API接口,涵盖创建、实现、测试和部署接口的关键步骤。同时,讨论了接口的安全性设计和设计原则,帮助开发者构建高效、安全、易于维护的API接口。
29 4
|
13天前
|
SQL Java 程序员
倍增 Java 程序员的开发效率
应用计算困境:Java 作为主流开发语言,在数据处理方面存在复杂度高的问题,而 SQL 虽然简洁但受限于数据库架构。SPL(Structured Process Language)是一种纯 Java 开发的数据处理语言,结合了 Java 的架构灵活性和 SQL 的简洁性。SPL 提供简洁的语法、完善的计算能力、高效的 IDE、大数据支持、与 Java 应用无缝集成以及开放性和热切换特性,能够大幅提升开发效率和性能。
|
14天前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
31 2
|
14天前
|
监控 Java 数据库连接
在Java开发中,数据库连接管理是关键问题之一
在Java开发中,数据库连接管理是关键问题之一。本文介绍了连接池技术如何通过预创建和管理数据库连接,提高数据库操作的性能和稳定性,减少资源消耗,并简化连接管理。通过示例代码展示了HikariCP连接池的实际应用。
16 1
|
7天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
14 0
|
8天前
|
Java API Android开发
kotlin和java开发优缺点
kotlin和java开发优缺点
21 0
WK
|
13天前
|
开发框架 移动开发 Java
C++和Java哪个更适合开发移动应用
本文对比了C++和Java在移动应用开发中的优劣,从市场需求、学习难度、开发效率、跨平台性和应用领域等方面进行了详细分析。Java在Android开发中占据优势,而C++则适合对性能要求较高的场景。选择应根据具体需求和个人偏好综合考虑。
WK
27 0
WK
|
14天前
|
安全 Java 编译器
C++和Java哪个更适合开发web网站
在Web开发领域,C++和Java各具优势。C++以其高性能、低级控制和跨平台性著称,适用于需要高吞吐量和低延迟的场景,如实时交易系统和在线游戏服务器。Java则凭借其跨平台性、丰富的生态系统和强大的安全性,广泛应用于企业级Web开发,如企业管理系统和电子商务平台。选择时需根据项目需求和技术储备综合考虑。
WK
16 0
|
18天前
|
算法 Java
JAVA 二叉树面试题
JAVA 二叉树面试题
14 0