树--排序二叉树的删除

一、二叉排序树的删除

二叉排序树的删除情况比较复杂,有以下三种情况需要考虑。

  1. 删除叶子节点 (比如:2,5,9,10)
  2. 删除只有一个子树的节点(比如:1)
  3. 删除有两个子树的节点 (比如:7,3,10)

分析情况一

删除叶子节点 (比如:2,5,9,10)思路:

分析情况二

删除只有一个子树的节点(比如:1)思路:

分析情况三

删除有两个子树的节点 (比如:7,3,10)思路:

二、代码实现

1.查找相应的节点

/**
 *
 * @param value  希望删除的节点值
 * @return       如果找到返回该节点值,找不到返回null
 */
public TreeNode search(TreeNode node,int value){

    if(root == null){
        return null;
    }

    // 找到的就是这个节点
    if(value == node.getValue()){
        return node;
    }else if(value < node.getValue()){ //如果查找的值小于当前节点向左子树递归查找
        // 判断左子树是否为空
        if(node.getLeftTreeNode() == null){
            return  null;
        }
       return search(node.getLeftTreeNode(),value);
    }else {
        if(node.getRightTreeNode() == null){
            return null;
        }
        return search(node.getRightTreeNode(),value);
    }

}

2.查找节点的父节点

/**
 *  查找节点的父节点
 * @param node   父节点
 * @param value  节点的值
 * @return       父节点
 */
public TreeNode SearchParent(TreeNode node,int value) {
    // 当前树为空树
    if(root == null){
        return null;
    }

     // 如果当前节点就是我们想要删除的节点的父节点,就返回
    if((node.getLeftTreeNode() != null && node.getLeftTreeNode().getValue() == value) ||
            (node.getRightTreeNode() !=null && node.getRightTreeNode().getValue() == value)){
        return node;
    }else {
        // 如果当前节点的值小于当前节点的值,并且当前节点的左子树不为空
        if(  node.getLeftTreeNode() !=null && value < node.getValue()){
            return SearchParent(node.getLeftTreeNode(),value); //左子树递归查找
        }else if( node.getRightTreeNode() !=null && value > node.getValue()){
            return SearchParent(node.getRightTreeNode(),value);//右子树递归查找
        }else {
            return null; // 没有找到父节点
        }
    }
}

3.找到右子树当中的最小值

/**
 * 找到右子树当中的最小值
 *
 * @param node 节点
 * @return     节点最小值
 */
public int delRightTreeMin(TreeNode node){
    //定义遍历的指针
   TreeNode target = node;

   // 循环的查询左子树,就会找到最小值
    while (target.getLeftTreeNode() !=null){
        target = target.getLeftTreeNode();
    }


    // 此时 target 执向最小值
    // 删除最小的节点 //这个地方传值要注意:一定是root
    // 因为如果传的值是parent是没有父节点的,会导致 父节点没有办法和子节点相连
    delNode(root,target.getValue());
    return target.getValue();
}

4.删除方法的实现


/**
 * 删除方法
 * @param node
 * @param value
 */
public void delNode(TreeNode node,int value){
    if(node == null){
        return;
    }
    //1.找到先删除的节点
    TreeNode targetNode = search(node,value);
    //如果没有找到要删除的节点
    if(targetNode == null){
      return;
    }
    //如果我们发现这颗二叉树只有一个节点
    if(node.getLeftTreeNode() == null && node.getRightTreeNode() == null){
        // 删除
        root = null;
        return;
    }

    // 找到targetNode的父节点
    TreeNode parent = SearchParent(node,value);


    //如果要删除的节点是叶子节点
    if(targetNode.getLeftTreeNode() == null && targetNode.getRightTreeNode() == null){
        // 判断targetNode是父节点的左子节点还是右子节点
        if(parent.getLeftTreeNode() !=null && parent.getLeftTreeNode().getValue() == value){
            parent.setLeftTreeNode(null);
        }else if(parent.getRightTreeNode() !=null && parent.getRightTreeNode().getValue() == value){
            parent.setRightTreeNode(null);
        }
    }else if(targetNode.getLeftTreeNode() != null && targetNode.getRightTreeNode() !=null){
        //删除有两颗子树的节点
        //System.out.println(targetNode.getValue());
        int minValue = delRightTreeMin(targetNode.getRightTreeNode());
        targetNode.setValue(minValue);
    }else {  //删除只有一颗子树的节点
        //如果要删除的节点有左子节点
        if(targetNode.getLeftTreeNode() !=null){
            if(parent.getLeftTreeNode().getValue() == value){
                //如果targetNode是parent的左子节点
                parent.setLeftTreeNode(targetNode.getLeftTreeNode());
            }else {  //如果targetNode是parent的右子节点
                parent.setRightTreeNode(targetNode.getLeftTreeNode());
            }
        }else {
            System.out.println("parent:"+parent);
            if(parent.getLeftTreeNode().getValue() == value){
                //如果targetNode是parent的左子节点
                parent.setLeftTreeNode(targetNode.getRightTreeNode());
            }else {//如果targetNode是parent的右子节点
                parent.setRightTreeNode(targetNode.getRightTreeNode());
            }
        }
    }

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【测试思考】当我给互联网姐妹解读电商大促规则

20年初&#xff0c;疫情开始&#xff0c;我和同事好不容易回家过年了&#xff0c;但是无法返沪&#xff0c;只能远程上班。 远程上班的效率比我想象的高很多&#xff0c;上班时间也比我想象的拉长很多&#xff0c;抛开这些扯远了&#xff0c;我们当时在做一个优惠券的项目。 下…

java学习——消息队列MQ

上一篇传送门&#xff1a;点我 目前只学习了RabbitMQ&#xff0c;后续学习了其他MQ后会继续补充。 MQ有了解过吗&#xff1f;说说什么是MQ&#xff1f; MQ是Message Queue的缩写&#xff0c;也就是消息队列的意思。它是一种应用程序对应用程序的通信方法&#xff0c;使得应用…

【解决】Spring Boot创建项目常见问题

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;Spring学习之路&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 idea无maven选项 无效发行版17 类⽂件具有错误的版本 61.0, 应为 …

基于PyAutoGUI图片定位的自动化截图工具--完成了

1、计划 压测完成后需要编写性能测试报告&#xff0c;报告中所需数据截图较多&#xff0c;使用自动化操作方便快捷&#xff0c;就编写一个界面工具以便后续复用。 基于PyAutoGUI图片定位的自动化截图工具–jmeter部分 基于PyAutoGUI图片定位的自动化截图工具–jmeter部分&#…

js纯前端实现语音播报,朗读功能(2024-04-15)

实现语音播报要有两个原生API 分别是【window.speechSynthesis】【SpeechSynthesisUtterance】 项目代码 // 执行函数 initVoice({text: 项目介绍,vol: 1,rate: 1 })// 函数 export function initVoice(config) {window.speechSynthesis.cancel();//播报前建议调用取消的函数…

HCIP【ospf综合实验】

目录 实验要求&#xff1a; 实验拓扑图&#xff1a; 实验思路&#xff1a; 实验步骤&#xff1a; 一、划分网段 二、配置IP地址 三、搞通私网和公网 &#xff08;1&#xff09;先搞通私网&#xff08;基于OSPF协议&#xff0c;在各个路由器上进行网段的宣告&#xff0c…

使用icpc tool进行滚榜操作

前言 参加ACM的同学都知道&#xff0c;比赛非常有趣的环节就是赛后的滚榜环节&#xff0c;所以为了一个比赛的完整性&#xff0c;自己办比赛时也想要加入滚榜的操作&#xff0c;经过一段时间的研究学习&#xff0c;已经可以将滚榜程序与domjudege程序成功完成融合&#xff0c;…

BypassUAC漏洞挖掘和代码集成

什么是UAC UAC是UserAccountControl的缩写&#xff0c;即用户帐户控制。是Windows操作系统中的一种安全特性&#xff0c;旨在保护计算机不被未经授权的应用程序和操作所破坏。UAC通过提示用户是否允许某个应用程序或操作修改计算机的设置或访问敏感数据&#xff0c;来帮助用户…

AntDesign震撼发布!阿里企业级设计体系引领行业风向!

企业级产品设计系统Antdesign是蚂蚁集团经过大量项目实践和总结&#xff0c;逐步打磨出来的产品。随着近两年b端产品的逐渐白热化&#xff0c;越来越多的用户对更好的用户体验有了进一步的要求。 作为国内研发团队量身定制的在线协作工具&#xff0c;设计师可以直接预览并在即…

C语言 | Leetcode C语言题解之第25题K个一组翻转链表

题目&#xff1a; 题解&#xff1a; /* 定义保存两个地址的结构体* 用来保存反转后结果的头节点和尾节点*/ typedef struct {struct ListNode* head; struct ListNode* tail; } TwoAddress; // 反转中间链表 TwoAddress* reverse(struct ListNode* head){struct ListNode* pr…

Java IO流-字节流

简介 IO流的输入与输出&#xff0c;都在站在内存的角度来看的&#xff0c;因为毕竟是和内促你打交道的嘛&#xff01; 分类 IO流是可以根据方向&#xff0c;或者最小单位进行划分的 上述两两结合一下&#xff0c;就得到四种大的分类 IO流的继承体系 字节输入流InputStream 创建…

邮件群发系统如何确保效率?怎么评估性能?

邮件群发系统构建方法&#xff1f;邮件群发系统有哪些关键功能&#xff1f; 如何确保邮件群发系统的效率&#xff0c;以及如何评估其性能&#xff0c;却成为摆在众多使用者面前的一大问题。AokSend将围绕这两个方面展开讨论&#xff0c;帮助读者更好地理解和应用邮件群发系统。…

链表OJ1——删除链表中等于给定值 val 的所有节点

题目 力扣OJ链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 解法 我们来看看这个题目啊&#xff0c;怎么做呢&#xff1f; 有两种解法 三指针法 我们完全可以定义三个指针来进行这个删除操作 假设我们要移除的是2 这样子就完成了 特殊情况 开头——假设我们…

【学习】黑盒测试用例设计方法都有哪些

在软件测试中&#xff0c;黑盒测试是一种重要的测试方法&#xff0c;它专注于软件的外部行为&#xff0c;而不关心其内部结构和实现。黑盒测试的目标是确保软件的功能符合需求规格说明书中的要求。为了有效地进行黑盒测试&#xff0c;需要设计合理的测试用例。本文将详细介绍黑…

java:多线程中的死锁

多线程:死锁 当多个线程互相争抢资源导致都在互相等待资源的僵局时,如果没有外力,将会一直僵持下去,这就是死锁. 就像两个人分一双筷子,如果一人拿到一根筷子,都在等待对方手里的那根,将没有人能完成吃饭的任务. 死锁的必要条件 1,互斥 即资源只能被一个线程调用 2,不可剥…

idea 卡怎么办

设置内存大小 清缓存重启 idea显示内存全用情况 右下角

【图解】卖USDT的风险

张三涉足一项神秘行业&#xff0c;有时也会参与加密货币的交易。有一天&#xff0c;他添加了邵律师的微信&#xff0c;向他咨询&#xff1a;如何更安全地出售U币&#xff1f;因此&#xff0c;便有了这张图片。 他看了我的回复后叹了口气&#xff0c;说&#xff1a;“是的&#…

Docker容器tomcat中文名文件404错误不一定是URIEncoding,有可能是LANG=zh_CN.UTF-8引起

使用Docker部署tomcat&#xff0c;出现中文名文件无法读取&#xff0c;访问就是404错误。在网上搜索一通&#xff0c;都说是在tomcat的配置文件server.xml中修改一下URIEncoding为utf-8就行&#xff0c;但是我怎么测试都不行。最终发现&#xff0c;是Docker启动时&#xff0c;传…

攻防世界---Reversing-x64Elf-100

1.下载附件&#xff0c;先查壳&#xff0c;无壳 2.用IDA分析&#xff0c;找到main函数&#xff0c;使用fnf5&#xff0c;反编译 3.分析代码 4.双击进入条件函数中查看代码 5.编写代码&#xff0c;来源&#xff1a;https://blog.csdn.net/2303_80796023/article/details/1370866…

Kingbase(人大金仓数据库)(总结全网精华,虚拟机:从安装到操作数据库一条龙)

前言&#xff1a; 前一阵子一直在捣鼓人大金仓数据库&#xff0c;虽然国产化的数据库很值得夸赞&#xff0c;但是网上的资料确实少的可怜。特此记录一下我在学习这个数据库的心酸历程。 安装就看这个大哥的&#xff0c;我之前安装就是看的他的&#xff0c;非常靠谱。 linux安装…