有序二叉树java实现

news2024/10/6 10:35:56

类实现:

package 树;


import java.util.LinkedList;
import java.util.Queue;

public class BinaryTree {
    public TreeNode root;
    //插入
    public void insert(int value){
        //插入成功之后要return结束方法
        TreeNode node = new TreeNode(value);
        //如果root为空的话插入
        if(root == null){
            root = node;
            return;
        }

        //定义游标遍历二叉树
        TreeNode index = root;
        while (true){
            if(index.value<value){
                //要插入的节点是大的
                if(index.right==null){
                    //插入
                    index.right=node;
                    return;
                }
                index = index.right;
            }else {
                //新插入的值小
                if(index.left==null){
                    index.left=node;
                    return;
                }
                index = index.left;
            }
        }
    }
    //广度优先搜索,借助队列实现,如果队列不为空的话就让队列头出队,将出队的左右孩子依次进队
    public void levelOrder(){
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        if(root!=null){
            queue.add(root);
        }else {
            System.out.println("树为空,请先插入数据");
        }
        while ((!queue.isEmpty())){
            TreeNode index = queue.poll();
            System.out.print(index.value + " ");
            if(index.left!=null){
                queue.add(index.left);
            }
            if(index.right!=null){
                queue.add(index.right);
            }
        }
        System.out.println();
    }
    //先序遍历
    public void beforeOrder(TreeNode node){
        if(node == null){
            return;
        }
        System.out.print(" "+node.value+" ");
        beforeOrder(node.left);
        beforeOrder(node.right);
    }
    //中序遍历
    public void inOrder(TreeNode node){
        if(node == null){
            return;
        }
        inOrder(node.left);
        System.out.print(" "+node.value+" ");
        inOrder(node.right);
    }
    //后序遍历
    public void adterOrder(TreeNode node){
        if(node == null){
            return;
        }
        adterOrder(node.left);
        adterOrder(node.right);
        System.out.print(" "+node.value+" ");
    }
    //查找
    public TreeNode seach(int value){
        if(root==null){
            return null;
        }
        //如果不是空的话,定义一个游标,指向根节点
        TreeNode index = root;
        while (index.value!=value){
            //如果目标值大
            if(index.value<value){
                index = index.right;
            }else {
                index = index.left;
            }
            if (index==null){
                return null;
            }
        }
        return index;
    }
    //查找节点的父节点
    public TreeNode searchParent(int value){
        if (root==null){
            return null;
        }
        //如果不是空的话,定义一个游标,指向根节点
        TreeNode index = root;
        //判断treeNode是不是目标节点的父节点
        while (true){
            if((index.left!=null&&index.left.value==value)||(index.right!=null&&index.right.value==value)){
                return index;
            }else if (value>index.value&&index.right!=null){
                //目标值大,index游标往右走
                index = index.right;
            }else if (value<index.value&&index.left!=null){
                //目标值小,index游标往左走
                index = index.left;
            }else {
                //没有父节点
                return null;
            }
        }
    }
    //找一棵树中的最小值
    public int min(TreeNode node){
        TreeNode index = node;
        if(index.left!=null){
            index = index.left;
        }
        return index.value;
    }
    //找一棵树中的最大值
    public int max(TreeNode node){
        TreeNode index = node;
        if(index.right!=null){
            index = index.right;
        }
        return index.value;
    }
    //删除
    public  void delete(int value){
        if (root==null){
            System.out.println("此树为空,无需删除");
            return;
        }
        //找到要删除的目标节点
        TreeNode targer = seach(value);
        //没有找到目标节点
        if (targer==null){
            System.out.println("没有此节点");
            return;
        }
        //找目标节点的父节点
        TreeNode parent = searchParent(value);

        //分为三大类
        if (targer.left==null&&targer.right==null){
            //删除叶子节点

            //如果没有父节点
            if (parent==null){
                root = null;
                return;
            }
            //如果有父节点
            //确定要删除的节点是父节点的左孩子还是右孩子
            if (parent.left!=null&&parent.left.value==value){
                parent.left = null;
            }else {
                parent.right = null;
            }
        }else if (targer.left!=null&&targer.right!=null){
            //删除有两棵子树的节点
            //找到目标节点右子树的最小值(或者左子树的最大值)
            int min = min(targer.right);
            //删除最小值的节点
            delete(min);
            //目标节点的值被最小值覆盖
            targer.value = min;
        }else {
            //删除只有一棵字数的节点

            //如果没有父节点
            if (parent==null){
                //判断目标节点有左子树还是有右子树
                if(targer.left!=null){
                    //有左子树
                    root = targer.left;
                }else {
                    //有右子树
                    root = targer.right;
                }
                return;
            }
            //有父节点
            //确定要删除的节点是父节点的左孩子还是右孩子
            if (parent.left!=null&&parent.left.value==value){
                //要删除的节点是父节点的左孩子
                //判断目标节点有左孩子还是右孩子
                if(targer.left!=null){
                    //有左孩子
                    parent.left = targer.left;
                }else {
                    //有右孩子
                    parent.left = targer.right;
                }
            }else {
                //要删除的节点是父节点的右孩子
                //判断目标节点有左孩子还是右孩子
                if(targer.left!=null){
                    //有左孩子
                    parent.right = targer.left;
                }else {
                    //有右孩子
                    parent.right = targer.right;
                }
            }
        }
    }
}

Test测试:

package 测试;

import 树.BinaryTree;


public class TreeTest {
    public static void main(String[] args) {
//        TreeNode t1 = new TreeNode(6);
//        TreeNode t2 = new TreeNode(11);
//        TreeNode t3 = new TreeNode(18);
//        TreeNode t4 = new TreeNode(3);
//        TreeNode t5 = new TreeNode(32);
//        TreeNode t6 = new TreeNode(8);
//        TreeNode t7 = new TreeNode(16);
//
//        t1.left = t4;
//        t1.right = t6;
//        t2.left = t6;
//        t2.right = t7;
//        t3.left = t7;
//        t3.right = t5;
//        System.out.println(t1);

        BinaryTree tree = new BinaryTree();
        BinaryTree tree1 = new BinaryTree();
        tree.insert(10);
        tree.insert(15);
        tree.insert(21);
        tree.insert(8);
        tree.insert(9);
        tree.insert(1);
        tree.insert(12);
        tree.insert(19);
        System.out.println(tree.root);
        tree.levelOrder();
        tree1.levelOrder();
        System.out.print("先序遍历为:");
        tree.beforeOrder(tree.root);
        System.out.println();
        System.out.print("中序遍历为:");
        tree.inOrder(tree.root);
        System.out.println();
        System.out.print("后序遍历为:");
        tree.adterOrder(tree.root);
        System.out.println();
        System.out.println("==========================");
        System.out.println("删除之后:");
        tree.delete(15);
        System.out.print("先序遍历为:");
        tree.beforeOrder(tree.root);
        System.out.println();
        System.out.print("中序遍历为:");
        tree.inOrder(tree.root);
        System.out.println();
        System.out.print("后序遍历为:");
        tree.adterOrder(tree.root);
    }
}

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1807126.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nacos的配置中心

1.前言 除了注册中心和负载均衡之外, Nacos还是⼀个配置中心, 具备配置管理的功能. Namespace 的常用场景之一是不同环境的配置区分隔离&#xff0c; 例如开发测试环境和⽣产环境的配置隔离。 1.1 为什么需要配置中心&#xff1f; 当前项目的配置都在代码中&#xff0c;会存…

6.7.12 使用 SWIN Transformer 通过热图像实现乳腺癌检测系统

乳腺癌是重大的公共卫生挑战&#xff0c;需要有效的诊断方法。虽然超声、乳房 X 线照相和 MRI 仍然至关重要&#xff0c;但它们在定期、短间隔大规模筛查中的实用性有限。 热成像作为一种非侵入性且经济有效的选择&#xff0c;具有常规自我筛查的潜力。本研究利用基于自注意力…

java中异常-异常概述+异常体系结构

一、异常概述 1、什么是异常&#xff1f; java程序在运行时出现的不正常情况 2、java中提供的默认的异常处理机制 java中对java程序运行时可能会出现的每种不正常情况都创建了一个唯一对应的类&#xff0c;在java程序运行时如果出现不正常情况&#xff0c;java程序就会创建…

数据结构:旋转数组

方法1 &#xff08;三次逆置法&#xff09;&#xff1a; void reverse(int* nums, int start, int end) {while (start < end) {int temp nums[start];nums[start] nums[end];nums[end] temp;start;end--;} }void rotate(int* nums, int numsSize, int k) {k k % numsS…

Java:111-SpringMVC的底层原理(中篇)

这里续写上一章博客&#xff08;110章博客&#xff09;&#xff1a; 现在我们来学习一下高级的技术&#xff0c;前面的mvc知识&#xff0c;我们基本可以在67章博客及其后面相关的博客可以学习到&#xff0c;现在开始学习精髓&#xff1a; Spring MVC 高级技术&#xff1a; …

Comfyui容器化部署与简介

目前使用 Stable Diffusion 进行创作的工具主要有两个&#xff1a;Stable Diffusion WebUI 和 ComfyUI。本文重点介绍ComfyUI的部署使用。 ComfyUI 可定制性很强&#xff0c;可以让创作者搞出各种新奇的玩意&#xff0c;通过工作流的方式&#xff0c;也可以实现更高的自动化水平…

SwiftUI五视图动画和转场

代码下载 使用SwiftUI可以把视图状态的改变转成动画过程&#xff0c;SwiftUI会处理所有复杂的动画细节。在这篇中&#xff0c;会给跟踪用户徒步的图表视图添加动画&#xff0c;使用animation(_:)修改器给一个视图添加动画效果非常容易。 下载起步项目并跟着本篇教程一步步实践…

Linux 内核之 mmap 内存映射触发的缺页异常 Page Fault

文章目录 前言一、简介1. MMU 内存管理2. 缺页中断3. 页表4. 小节 二、mmap 提前分配物理内存1. mm_populate 函数2. __mm_populate 函数3. populate_vma_page_range 函数4. __get_user_pages 函数5. find_extend_vma 函数6. find_vma 函数7. follow_page_mask 函数8. follow_p…

专业场景化ChatGPT论文润色提示词指令,更精准、更有效辅助学术论文撰写

大家好&#xff0c;感谢关注。我是七哥&#xff0c;一个在高校里不务正业&#xff0c;折腾学术科研AI实操的学术人。可以添加我&#xff08;yida985&#xff09;交流学术写作或ChatGPT等AI领域相关问题&#xff0c;多多交流&#xff0c;相互成就&#xff0c;共同进步。 在学术写…

数据分析必备:一步步教你如何用Pandas做数据分析(21)

1、Pandas 可视化 Pandas 可视化是指使用 Pandas 库中的函数和方法来创建数据可视化图表。Pandas 提供了一些基本的绘图功能&#xff0c;例如折线图、柱状图、饼图等&#xff0c;可以通过调用相应的函数来创建这些图表。 2、基本绘图&#xff1a;绘图 Series和DataFrame上的…

数据库四种隔离等级

持续更新以及完善中… 数据库事务隔离 首先&#xff0c;为什么要有事务隔离呢&#xff1f; 在单线程下&#xff0c;没什么大碍&#xff0c;但是我们想要提高效率&#xff0c;采用多线程并发时&#xff0c;便会出现一些问题。 **下面的问题一定要当作一个事务来看待&#xf…

高考之后第一张大流量卡应该怎么选?

高考之后第一张大流量卡应该怎么选&#xff1f; 高考结束后&#xff0c;选择一张合适的大流量卡对于准大学生来说非常重要&#xff0c;因为假期期间流量的使用可能会暴增。需要综合考虑多个因素&#xff0c;以确保选到最适合自己需求、性价比较高且稳定的套餐。以下是一些建议…

MAVEN架构项目管理工具

1、什么是maven Maven是跨平台的项目管理工具。主要服务于基于Java平台的项目构建&#xff0c;依赖管理和项目信息管理。 2、maven的目标&#xff1a;Maven的主要目标是为了使开发人员在最短的时间内领会项目的所有状态 3、使用maven不需要考虑各个依赖的版本&#xff0c;因…

指针(初阶2)“野指针以及指针运算”

目录 一.野指针 二.如何避免野指针 三.指针运算 1、指针&#xff08;-&#xff09;整数 2、指针 - 指针 3、指针关系运算 小编在这里声明一下&#xff0c;将某一块的知识点分为上中下或者1&#xff0c;2&#xff0c;3来编写不是为了增加小编的文章总量&#xff0c;也不是故意这…

MySQL之多表查询—列子查询

一、引言 标量子查询上篇博客已学习。接下来这篇博客学习子查询的第二种形式——列子查询 列子查询 子查询返回的结果是一列&#xff08;当然也可以是多行)&#xff0c;这种子查询称为列子查询。 列子查询可以使用的操作符 IN、NOT IN 、ANY&#xff08;any&#xff09;、SOME…

windows域控共享网络驱动器

背景 假设在一家公司&#xff0c;有新入职的员工。我们给其创建了域账号&#xff0c;有一些共享的文件需要其可以直接访问到。我们可以采用共享目录的形式&#xff0c;但是每次都要输入共享端的ip或者主机名&#xff0c;比较麻烦。我们希望创建的域账号访问共享文件更便捷一些…

使用Flask框架在Python中获取HTTP请求头信息

目录 引言 一、Flask框架简介 二、获取HTTP请求头的方法 三、案例分析 案例一&#xff1a;基于请求头进行用户身份验证 案例二&#xff1a;基于请求头的内容类型处理不同格式的响应 四、总结 引言 在Web开发领域&#xff0c;HTTP协议是客户端和服务器之间进行通信的基础…

爆破信息壁垒!多少考研人还在盲目刷题?

有些同学&#xff0c;天生擅长冲锋陷阵&#xff0c;不擅长思考总结。 忌&#xff1a;看视频一日千里&#xff0c;看例题从不动笔。 —— 新知识都“会”&#xff0c;旧知识都不会。 大忌&#xff1a;做题没思路&#xff0c;一看答案都会&#xff01; 24的学长学姐&#xff0c…

抽象的java入门1.3.2

前言&#xff1a; 全新版本的函数&#xff08;方法&#xff09;定义&#xff0c;更简单 1.优化了验证过程&#xff0c;直击本质 2.新增目前一图流 正片&#xff1a; 函数的结构可以分为三部分&#xff1a;函数名&#xff0c;参数&#xff0c;函数体 一生二&#xff0c;二生…

VS2019专业版 C#和MFC安装

1. VS2019专业版下载地址 https://learn.microsoft.com/en-us/visualstudio/releases/2019/history 2.安装 C# 部分 MFC部分