二叉查找树

news2024/11/28 9:26:23

目录

一、二叉查找树概念

二、结点内部类代码实现:

 三、二叉查找树的插入原理​编辑

四、遍历的方式(中序遍历): 

五、二叉查找树实现指定值删除对应的结点

六、main方法测试


一、二叉查找树概念

二、结点内部类代码实现:

public class BinarySearchTree {

    //写一个结点内部类
    public static class Node{
        int value;
        Node left;
        Node right;
        public Node(int value){
            this.value = value;
        }
    }

    //先定义一个根节点
    Node root;
}

 三、二叉查找树的插入原理

//写一个插入类
    public void insert(int value){
        //如果树为null,则直接插入在根节点上
        if (root == null){
            root = new Node(value);
        }
        //声明一个游标结点,开始指向根节点
        Node node = root;
        //如果树不为null,则比较插入的值与根节点的大小,小放左边大放右边
        while(true){
            if (value < node.value){
                //如果root.left为null,则直接插入到root.left中
                if (node.left == null){
                    node.left = new Node(value);
                    break;
                }else{
                    //将游标指向左子节点
                    node = node.left;
                }
            }else {
                if (node.right ==null){
                    node.right = new Node(value);
                    break;
                }else {
                    //将游标指向右子节点
                    node = node.right;
                }
            }
        }
    }

四、遍历的方式(中序遍历): 

1.通过中序遍历就可以将二叉查找树进行顺序输出。

2.中序遍历的特征:左、根、右 

通过中序遍历,刚好可以把二叉查找树从小到大进行遍历输出。

//实现中序遍历
    public void midTraversal(Node node){
        if (node == null){
            return;
        }
        //先遍历左子节点
        midTraversal(node.left);
        //打印根节点
        System.out.print(node.value+" ");
        //再遍历右子节点
        midTraversal(node.right);
    }

五、二叉查找树实现指定值删除对应的结点

public static final int LEFT = 0;
    public static final int RIGHT = 1;
    //实现删除指定结点
    public void deleteNode(int value){
        //定义一个游标指针
        Node node = root;
        //定义一个目标结点
        Node target = null;
        //定义一个target的父类结点
        Node parent = null;
        //定义一个结点类型,左结点为0,右节点为1
        int nodeType = 0;

        //先进行查找目标元素
        while (node != null){//当node等于null的时候说明树中没有目标结点
            if (node.value == value){
                //找到结点了
                target = node;
                break;
            }else if (value < node.value){
                parent = node;//先记录node的父节点
                node = node.left;//node往左下方遍历
                nodeType = LEFT;
            }else {
                parent = node;
                node = node.right;
                nodeType = RIGHT;
            }
        }

        //如果target为null,则表示树中没有此节点
        if (target == null){
            System.out.println("没有找到要删除的结点");
        }

        //删除结点的三种方式,原理有两种,一种是将父类结点的指针指向新的子节点,
        // 另一种是将一个子节点的值替换掉目标结点,同时删除那个替换的子节点。
        //1.如果结点是叶子结点,也就是没有子节点的情况
        if (target.left == null && target.right == null){
            //如果树只有一个根节点,删除根节点的情况
            if (parent == null){
                //将root设置为null即可
                root = null;
                return;
            }
            //判断目标的结点是左子节点还是右子节点
            if (nodeType == LEFT){
                parent.left = null;
            }else{
                parent.right = null;
            }
        }else if (target.left != null && target.right != null){
            //2.如果删除的结点有两个子节点的情况
            //这种情况下,我们可以选择目标结点的左子树中最大的结点替换目标结点,
            // 也可以选择右子树中最小的结点替换掉目标结点

            //从target的右子树中查找最小的值
            Node min = target.right;
            while (min.left != null){
                min = min.left;
            }
            //将右子树中最小的值的结点删除
            deleteNode(min.value);
            //将最小值覆盖到目标结点上,完成目标结点的删除
            target.value = min.value;
        }else{
            //如果删除的是根节点,且根节点只有一个子节点
            if (parent == null){
                if (target.left != null){
                    root = target.left;
                }else {
                    root = target.right;
                }
                return;
            }
            //3.如果删除的结点只有一个子节点的情况
            if (nodeType == LEFT){
                if (target.left != null){
                    //将父类的子节点指向待删除子节点的左子节点
                    parent.left = node.left;
                }else {
                    //将父类的子节点指向待删除子节点的右子节点
                    parent.left = node.right;
                }
            }else {
                if (target.left != null){
                    //将父类的子节点指向待删除子节点的左子节点
                    parent.right = node.left;
                }else {
                    //将父类的子节点指向待删除子节点的右子节点
                    parent.right = node.right;
                }
            }
        }
    }

六、main方法测试

package Tree.BinarySearchTree;

public class TestBinarySearchTree {
    public static void main(String[] args) {
        int[] arr2 = {5,2,1,4,3,9,7,6,8};

        BinarySearchTree bst2 = new BinarySearchTree();
//        //将数组中的元素构造成二叉查询树
        for (int i = 0;i<arr2.length;i++){
            bst2.insert(arr2[i]);
        }
        //中序遍历
        bst2.midTraversal(bst2.root);
        //删除指定元素
        bst2.deleteNode(9);
        System.out.println();
        bst2.midTraversal(bst2.root);
    }
}

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

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

相关文章

聚类问题的算法总结

目录 一、K-means算法 1、算法原理 2、如何确定K值 3、算法优缺点 二、DBScan聚类 1、算法原理 2、处理步骤 3、算法优缺点 聚类代码实现 聚类算法属于无监督学习&#xff0c;与分类算法这种有监督学习不同的是&#xff0c;聚类算法事先并不需要知道数据的类别标签&am…

高效释放数据价值,数智融合平台有门道

在数字经济时代&#xff0c;数据上升为新的关键生产要素&#xff0c;逐渐超越土地、资本等传统要素&#xff0c;成为社会经济发展和企业创新更加重要的驱动力。 但如何充分释放数据价值在当下依然是一个世界性难题。一方面&#xff0c;企业与组织逐渐拥有海量数据规模和丰富应…

基于CBC、ECB、CTR、OCF、CFB模式的AES加密算法

1、什么是AES加密算法 什么是加密算法&#xff1f;我在文章《从个人角度看什么是加密算法》中描述了我对加密算法的一些浅薄的理解。我不是信息安全领域的大神&#xff0c;只求有一个入门罢了&#xff01; 这篇文章是文章《从个人角度看什么是加密算法》的延伸&#xff0c;所…

【C++初阶】:缺省函数和函数重载

c入门一.缺省函数二.函数重载1.参数类型不同2.参数个数不同3.参数顺序不同一.缺省函数 缺省函数&#xff0c;顾名思义就是可以在传参时不传或者少传参数的函数。这里举个例子&#xff1a; 完全缺省 上面的就属于全缺省&#xff0c;可以不传任何参数&#xff0c;当然也可以传参…

Codeforces Round 862 (Div. 2) -- D. A Wide, Wide Graph(树的直径 贪心 简单的树形dp)

题目如下&#xff1a; 题意简说&#xff1a; 树上两点 u,vu, vu,v&#xff0c;如果 u,vu, vu,v 的距离大于等于 kkk 则在图 GkG_kGk​ 上 u,vu, vu,v 有一条无向边。 求当 kkk 等于 [1, n] 的时候&#xff0c;图 GkG_kGk​ 的连通块数量。 思路 or 题解&#xff1a; 我们可以…

【服务器】Dell PowerEdge R750 安装GPU

各种教程 官方教程 https://www.dell.com/support/manuals/zh-cn/poweredge-r750/per750_ism_pub/%E5%AE%89%E8%A3%85-gpu?guidguid-6bb1c301-7595-4c6d-b631-b6a5761c6052&langzh-cn 手册PDF版&#xff1a; https://dl.dell.com/content/manual16153190-dell-emc-powe…

OKR与敏捷开发的结合

当你想达成某件事情时&#xff0c;你在内心会有一个设想的期望结果。这是一个非常简单、基本的概念&#xff0c;并且是从很多人小时候就培养起来的。我们可以将这种现象总结一句话&#xff1a; 通过 ________ 来衡量__________ 。 这就是 John Doerr 在其著作《Measure what Ma…

JavaWeb开发 —— Maven

目录 一、概述 1. 介绍 2. 安装 二、maven-idea 集成 1. 配置及创建Maven项目 2. IDEA 创建Maven项目 3. IDEA导入 Maven 项目 三、依赖管理 1. 依赖配置 2. 依赖传递 3. 依赖范围 4. 生命周期 一、概述 1. 介绍 ① Apache Maven 是一个项目管理和构建工…

【UDP报文和TCP协议特性】

目录1.UDP报文1.1报文长度1.2校验和2.TCP协议特性2.1确认应答2.2超时重传2.3连接管理2.3.1三次握手2.3.2四次挥手2.4滑动窗口2.5流量控制2.6拥塞控制2.7延时应答2.8捎带应答2.9面向字节流2.10异常情况3.小结3.1tcp小结3.2tcp和UDp应用场景的差异4.寄语1.UDP报文 udp是传输层最…

【Android】之【内存管理】

一、Android内存运行是如何运行的&#xff1f; 物理内存即移动设备上的ram&#xff0c;当启动一个android程序时&#xff0c;会启动一个dalvik vm进程&#xff0c;系统会给它分配固定的内存空间【16m,32m,64m,不定&#xff0c;没有统一标准&#xff0c;每个虚拟机会有堆内存阈…

【Minecraft开服教程】使用 MCSM 面板一键搭建我的世界服务器,并内网穿透公网远程联机

文章目录前言1.Mcsmanager安装2.创建Minecraft服务器3.本地测试联机4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射内网端口5.远程联机测试6. 配置固定远程联机端口地址6.1 保留一个固定TCP地址6.2 配置固定TCP地址7. 使用固定公网地址远程联机前言 MCSManager是一个开源…

C++ float 数据的保存格式

总体上&#xff0c;在计算机中&#xff0c; float 数据的的保存按照如下转换逻辑&#xff1a;10进制数 >二进制数>科学计数法二进制数>c 条件下下浮点数在内存中的保存格式&#xff08;这里面有个转换算法&#xff0c;需要理清楚&#xff09;。 下面举出一个案例&…

Python+selenium自动化测试实战项目(全面,完整,详细)

前言 之前的文章说过&#xff0c; 要写一篇自动化实战的文章&#xff0c; 这段时间比较忙再加回家过清明一直没有更新&#xff0c;今天整理一下实战项目的代码共大家学习。&#xff08;注:项目是针对我们公司内部系统的测试&#xff0c;只能内部网络访问&#xff0c;外部网络无…

使用fetch()异步请求API数据实现汇率转换器

任务8 https://segmentfault.com/a/1190000038998601 https://chinese.freecodecamp.org/news/how-to-master-async-await-with-this-real-world-example/ 跟随上面的指示&#xff0c;理解异步函数的编写&#xff0c;并且实现这个汇率转换器。 第一步&#xff1a;在工作区初始…

AI失业潮来袭,某些部门裁员过半

历史的车轮滚滚向前&#xff0c;每次生产力的大幅跃进&#xff0c;都会造成一批失业潮。想当年&#xff0c;纺纱机的出现让无数手工作坊的织布师傅失业。如今&#xff0c;在AI技术的催化下&#xff0c;同样的事正在互联网行业的各个领域重演。疯狂的裁员浪潮 “AI15秒做的&…

图神经网络汇总和总结

下面所有博客是个人对EEG脑电的探索&#xff0c;项目代码是早期版本不完整&#xff0c;需要完整项目代码和资料请私聊。 数据集 1、脑电项目探索和实现(EEG) (上)&#xff1a;研究数据集选取和介绍SEED 相关论文阅读分析&#xff1a; 1、EEG-SEED数据集作者的—基线论文阅读和…

LeetCode——二叉树的层序遍历

102. 二叉树的层序遍历 I 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]]…

超级详解MySQL执行计划explain

1、什么是MySQL执行计划 要对执行计划有个比较好的理解&#xff0c;需要先对MySQL的基础结构及查询基本原理有简单的了解。 MySQL本身的功能架构分为三个部分&#xff0c;分别是 应用层、逻辑层、物理层&#xff0c;不只是MySQL &#xff0c;其他大多数数据库产品都是按这种架构…

窗函数的总结

1. 为什么要加窗 每次FFT变换只能对有限长度的时域数据进行变换&#xff0c;因此&#xff0c;需要对时域信号进行信号截断。即使是周期信号&#xff0c;如果截断的时间长度不是周期的整数倍&#xff08;周期截断&#xff09;&#xff0c;那么&#xff0c;截取后的信号将会存在泄…

C++算法初级10——动态规划

C算法初级10——动态规划 文章目录C算法初级10——动态规划最优化问题动态规划分析流程和条件最优化问题 生活中我们常常遇到这样一些问题&#xff1a; 看到上面的例子&#xff0c;我们发现这些问题都是在最大化&#xff08;或者最小化&#xff09;某个指标&#xff1a;最小化…