学习笔记-二叉排序树

2023-11-11

二叉排序树

对于二叉排序树的任何一个非叶子节点,要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大。如果有相同的值,可以将该节点放在左子节点或右子节点。
在这里插入图片描述

二叉排序树的创建和遍历

思路:比较节点的值,小于就放在左子节点,大于就放在右子节点,如果子节点不为空,就递归添加。

	//添加节点
    public void add(Node node){
         if(node==null){
             return;
         }
         if(node.value<this.value){
             if(this.left==null){
                 this.left=node;
             }else{
                 this.left.add(node);
             }
         }else {
             if(this.right==null){
                 this.right=node;
             }else {
                 this.right.add(node);
             }
         }
    }
    //中序遍历
    public void midOrder(){
         if(this.left!=null){
             this.left.midOrder();
         }
        System.out.println(this);
         if(this.right!=null){
             this.right.midOrder();
         }
    }

二叉排序树删除节点

思路:首先要保证能根据值找到那个要删除的节点和它的父节点。
分为5种情况:

  1. 要删除的值不存在,也就是目标节点为null,直接返回。
  2. 只有一个根节点的情况,直接root=null。
  3. 要删除的是叶子节点。需判断目标节点是父节点的左子节点还是右子节点,通过parent.left=null或parent.right=null删除。
  4. 删除有一颗子树的节点。首先判断父节点是否为空,如果为空,情况就是删除有一棵子树的根节点,直接让root=target.left或.right。如果父节点不为空,就要判断目标节点是父节点的左右子节点和目标节点的子树是左右子树,一共对应4种可能性。
  5. 删除有两棵子树的节点。寻找右子树的最小值或左子树的最大值,将该值赋给目标节点,并将那个最小值或最大值节点删除。
package binarySortTree;

/**
 * 二叉排序树
 */
public class BinarySortTreeDemo {
    public static void main(String[] args) {
        int[] num={7, 3};
        BinarySortTree binarySortTree = new BinarySortTree();
        for(int i:num){
            binarySortTree.add(new Node(i));
        }
        binarySortTree.midOrder();
        System.out.println("-----------");
        binarySortTree.delNode(3);
        binarySortTree.midOrder();

    }
}
//二叉排序树
class BinarySortTree{
    Node root;
    //添加节点
    public void add(Node node){
        if(root==null){
            root=node;
        }else {
            root.add(node);
        }
    }
    //中序遍历
    public void midOrder(){
        if(root==null){
            System.out.println("空树");
        }else {
            root.midOrder();
        }
    }
    //寻找节点
    public Node search(int value){
        if(root==null){
            System.out.println("空树");
            return null;
        }else {
            return root.search(value);
        }
    }
    //寻找父节点
    public Node searchFather(int value){
        if(root==null){
            System.out.println("空树");
            return null;
        }else {
            return root.searchFather(value);
        }
    }
    //寻找某棵子树的最小值,返回并删除它
    public int searchMin(Node node){
        Node temp=node;
        while (temp.left!=null){
            temp=temp.left;
        }
        delNode(temp.value);
        return temp.value;
    }
    //删除节点
    public void delNode(int value){
        //空树
        if(root==null){
            return;
        }
        Node target=root.search(value);
        //说明没找到
        if(target==null){
            return;
        }
        //如果只有一个根节点
        if(root.left==null && root.right==null){
            root=null;
            return;
        }
        //要删除的是叶子节点
        Node parent=root.searchFather(value);
        if(target.left==null && target.right==null){
            //是左子节点
            if(parent.left!=null && target.value==parent.left.value){
                parent.left=null;
            }else if(parent.right!=null && target.value==parent.right.value) {
                //是右子节点
                parent.right=null;
            }
        }else if(target.left!=null && target.right!=null){
            //要删除的节点有两棵子树
            target.value=searchMin(target.right);
        }else {
            //要删除的节点有一棵子树
            //根节点有一棵子树
            if(parent==null){
                if(target.left!=null && target.value==root.value){
                    root=target.left;
                }else if(target.right!=null && target.value==root.value){
                    root=target.right;
                }
            }else {
                //非根节点有一棵子树
                //是父的左子树
                if(parent.left!=null && parent.left.value==target.value){
                    //目标有左子树
                    if(target.left!=null){
                        parent.left.value=target.left.value;
                        target.left=null;
                    }else {
                        //目标有右子树
                        parent.left.value=target.right.value;
                        target.right=null;
                    }
                }else {
                    //是父的右子树
                    //目标有左子树
                    if(target.left!=null){
                        parent.right.value=target.left.value;
                        target.left=null;
                    }else {
                        //目标有右子树
                        parent.right.value=target.right.value;
                        target.right=null;
                    }
                }
            }
        }

    }
}

//树节点
class Node{
     int value;
     Node left;
     Node right;

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }

    public Node(int value){
         this.value=value;
     }
     //查找节点
    public Node search(int value){
        if(this.value==value){
            return this;
        }else {
            if(value<this.value){
                if(this.left!=null){
                    return this.left.search(value);
                }else {
                    return null;
                }
            }else {
                if(this.right!=null){
                    return this.right.search(value);
                }else {
                    return null;
                }
            }
        }
    }
    //查找节点的父节点
    public Node searchFather(int value){
        if(this.left!=null && this.left.value==value ||this.right!=null && this.right.value==value){
            return this;
        }
        if(this.left!=null && value<this.value){
            return this.left.searchFather(value);
        }else if(this.right!=null && value>=this.value){
            return this.right.searchFather(value);
        }else {
            return null;
        }
    }
     //添加节点
    public void add(Node node){
         if(node==null){
             return;
         }
         if(node.value<this.value){
             if(this.left==null){
                 this.left=node;
             }else{
                 this.left.add(node);
             }
         }else {
             if(this.right==null){
                 this.right=node;
             }else {
                 this.right.add(node);
             }
         }
    }
    //中序遍历
    public void midOrder(){
         if(this.left!=null){
             this.left.midOrder();
         }
        System.out.println(this);
         if(this.right!=null){
             this.right.midOrder();
         }
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

学习笔记-二叉排序树 的相关文章

随机推荐

  • node_modules安装及node-sass使用

    node modules安装及node sass使用 终端进入项目文件夹运行以下命令 一 安装node modules 1 输入npm init 一直回车 会生成package json文件 2 npm i D vue 然后就成功node
  • 第十二届蓝桥杯嵌入式总结及分享

    蓝桥杯嵌入式总结以及分享 这是我第一次写CSDN的文章 如果有什么写的不好的 还请各位见谅 不喜勿喷 谢谢 经过这两个星期时间准备省赛 两个星期准备国赛 最终取得了国二的成绩 个人认为这个比赛就是耗时长 我对源码不够熟悉 所以导致时间基本都
  • 走得最慢的人,只要他不丧失目标,也比漫无目的地徘徊的人走得快。

    走得最慢的人 只要他不丧失目标 也比漫无目的地徘徊的人走得快 莱辛 有着坚定明确的目标 且知道如何做能达成目标 没有追求 未来迷茫 或许大家都想当第一种人 但可能在不知不觉中就成了第二种人 自己也不知道 或是因为目标太大 难以后继 最终失却
  • 1049 数列的片段和

    给定一个正数数列 我们可以从中截取任意的连续的几个数 称为片段 例如 给定数列 0 1 0 2 0 3 0 4 我们有 0 1 0 1 0 2 0 1 0 2 0 3 0 1 0 2 0 3 0 4 0 2 0 2 0 3 0 2 0 3
  • Xshell缺少.dll文件解决方案

    背景 安装Xshell时报错 由于找不到MSVCR110 dll文件 无法继续执行代码 重新安装程序可能会解决此问题 这种情况是缺少运行库 解决方案 微软常用运行库 https pan baidu com s 1kgJRky3cicOMxR
  • 计算机打不开excel表格,excel表格打不开怎么办?excel表格打不开的原因及解决方法...

    今天有网友反映 他昨天做的Excel表格打不开了 但其他Excel表格是可以打开的 非常郁闷 那么Excel表格打不开是什么原因呢 Excel表格打不开怎么办呢 下面脚本之家小编就来说说有关造成Excel表格打不开的几种原因及解决办法 一
  • 基于Loung Attention+LSTM的机器翻译模型

    目录 需要掌握的基础知识 1 Encoder Decoder架构 2 LSTM模型原理 3 Attention机制 基于Loung Attention LSTM的机器翻译模型 模型 数据 训练 基于Bahdanau Attention LS
  • 大数据安全治理平台建设方案

    近年来 随着大数据应用的普及 在新基建 智慧城市 云端应用等大背景趋势下 给我们日常生活便来了很多方便 同时也派生出更多网络安全风险 如企业数据泄露 欺诈 数据违规使用 个人隐私泄露以及企业内部各种威胁和潜在风险 数据是宝贵的资源和财富 当
  • LCD操作原理

    一 LCD原理介绍 LCD内部内部结构 1 lcd由Framebuffer lcd屏幕 信号线 电子枪 lcd控制器组成 2 Framebuffer提供显示数据 lcd屏幕显示 信号线传输Frambuffer中的数据和lcd控制器发出的信号
  • 【深度学习】Attention提速9倍!FlashAttention燃爆显存,Transformer上下文长度史诗级提升...

    转载自 新智元 继超快且省内存的注意力算法FlashAttention爆火后 升级版的2代来了 FlashAttention 2是一种从头编写的算法 可以加快注意力并减少其内存占用 且没有任何近似值 比起第一代 FlashAttention
  • Sqli-labs Less-1 报错注入

    Sqli labs Less 1 报错注入 1 首先打开less1后是一个页面 提示输入id作为参数 输入id 1试一下 然后会出现 name 和 password 添加一个单引号 测试一下注入点 输入单引号发现 会直接将报错结果显示在页面
  • 模拟IC设计——MOS计算及常见MOS管电路

    小生初入模拟IC 作此笔记在大佬面前实属班门弄斧 若有不当之处还请指正 1 MOSFET概述 场效应管与晶体管一样 也具有放大作用 但与普通晶体管是电流控制型器件相反 场效应管是电压控制型器件 它具有输入阻抗高 噪声低的特点 1 MOSFE
  • 使用OpenCV中的matchTemplate函数实现模板匹配【C++版】

    matchTemplate函数原型 void cv matchTemplate InputArray image InputArray templ OutputArray result int method InputArray mask
  • THREEJS - 动态标签(dom方式)

    在三维场景中 我们会有一种需求 需要给三维场景中的模型打上标签 例如展示模型的名称 性能展示等 三维场景打标签的方式很多 有dom sprite Mesh等等 这篇文章来给大家介绍的是一种比较常见的打标签方式 dom 这种方式我们可以自定义
  • WSL2和本地windows端口互通

    众所周知 WSL 默认安装后 只允许windows访问 Windows Subsystem for Linux 而WSL是不能反之访问本地windows 我之前用vmware的思路认为是nat的网络模式 于是改成了桥接 结果wsl的桥接模式
  • springboot日志配输出路径配置_SpringBoot输出日志到文件

    1 基本信息 SpringBoot版本2 2 5 日志框架SLF4J 日志框架的实现LockBack 2 输出文件的配置 2 1 logging file name 指定日志文件的位置 2 1 1 例1 使用相对路径 就会在项目根目录下生成
  • R 语言散点图矩阵

    多个变量之间的关系经常用散点图矩阵表示 ggplot2 包没有提供专门的散点图矩阵 基础 R 图形中提供了 pairs 函数作散点图矩阵 GGally 包提供了一个 ggscatmat 函数作散点图矩阵 例如 对 iris 数据的四个测量值
  • UE4 C++ FString乱码显示问号

    如果以 xxx 这种形式并且xxx为中文时 直接赋值给FString的变量会丢失数据导致系统无法识别 因此需要做特殊处理 第一种解决办法 引号前加L表示将字符串转为unicode的字符串 也就是每个字符占用两个字节 FString str
  • 【无标题】DEFI+NFT新玩法

    DeFi NFT 去中心金融 非同质化货币 NFT Defi就是将流动性挖矿的方法移植到到NFT领域 目前典型的代表有MEME SAND RARI等 区块链行业一直困于 圈内自嗨 无法真正走入大众市场 市场和用户规模的增量相比互联网行业是杯
  • 学习笔记-二叉排序树

    二叉排序树 对于二叉排序树的任何一个非叶子节点 要求左子节点的值比当前节点的值小 右子节点的值比当前节点的值大 如果有相同的值 可以将该节点放在左子节点或右子节点 二叉排序树的创建和遍历 思路 比较节点的值 小于就放在左子节点 大于就放在右