数据结构——有序二叉树的删除

在上一篇博客中,我们介绍了有序二叉树的构建、遍历、查找。

数据结构——有序二叉树的构建&遍历&查找-CSDN博客文章浏览阅读707次,点赞18次,收藏6次。因为数据的类型决定数据在内存中的存储形式。left right示意为左右节点其类型也为TreeNode,用于接受后续一系列操作,保持了结构的一致性。为什么left和right的类型为TreeNode?我们采用递归的方式实现。我们创建一个test类。https://blog.csdn.net/2301_78566776/article/details/144160961?spm=1001.2014.3001.5501这篇博客我们来介绍一下有序二叉树的删除。

删除操作

删除操作的步骤相对复杂,因为需要处理三种情况:

1.要删除的节点是叶子节点(没有子节点)

删除叶子节点
        1.找到要删除的节点targetNode
        2.找到targetNode的父节点(考虑父节点是否存在)
        3.确定targetNode是parentNode的左子树还是右子树
        4.根据前面的情况进行删除
        左子树:parentNode.left=null;右子树:parentNode.right=null;

2.要删除的节点只有一个子节点

删除有一个子树的节点
        1.找到要删除的节点targetNode
        2.找到targetNode的父节点(考虑父节点是否存在)
        3.确定targetNode是左子树还是右子树
        4.确定targetNode有的是左子树还是右子树
        5.targetNode有的是左子树
                 parentNode.left = targetNode.left;——删除的节点是父节点的左子树
                 parentNode.right = targetNode.left;——删除的节点是父节点的右子树
        6.targetNode有的是右子树:

                 parentNode.left = targetNode.right;——删除的节点是父节点的左子树
                 parentNode.right = targetNode.right;——删除的节点是父节点的右子树       

3.要删除的节点有两个子节点

对于第三种情况,通常的做法是找到要删除节点的中序后继(或中序前驱),将其值替换到要删除的节点上,然后删除这个中序后继(或中序前驱)。

删除有两个子树的节点
        1.找到要删除的节点targetNode
        2.找到targetNode的父节点(考虑父节点是否存在)
        3.去找targetNode的右子树的左子树当中的最小值
        4.将targetNode的值和最小值的值进行互换
        5.删除最小值——即删除叶子节点(替换删除)

Java代码如下:
public TreeNode Search(TreeNode node,int value) {
		if (node == null) {
            return null; 
        }
		if (value==node.data) {
            return node; 
        }else if(value<node.data){
        	if(node.left!=null) {
        		return Search(node.left,value);
			}
        }else {
        	if(node.right!=null) {
        		return Search(node.right,value);
			}
        }
        
		return null;
		// TODO Auto-generated method stub

	}
public TreeNode SearchParent(TreeNode node,int value){
	if (node == null) {
        return null; 
    }
	if((node.left!=null&&node.left.data==value)||(node.right!=null&&node.right.data==value)){
		return node;
	}else {
		if(node.left!=null&&value<node.data) {
			return SearchParent(node.left,value);
		}else if(node.right!=null&&value>node.data) {
			return SearchParent(node.right,value);
		}else {
			return null;
		}
	}
	
}

	public int delRightTreeMin(TreeNode node){
	    TreeNode tempNode = node;
	    while (tempNode.left !=null){
	        tempNode = tempNode.left;
	    }
	
	    return tempNode.data; //最值进行返回
	}


	public void delete(TreeNode node,int value){
		if (node == null) {//空树,直接返回
	        return; 
	    }
		
		if(node.left==null&&node.right==null) {//单节点树,直接置空
			node=null;
			return;
		}
		
		//先查询要删除的节点
		TreeNode targetNode=Search(node,value);
		
		if(targetNode==null) {//没有找到
			return;
		}
		
		//找父节点
		TreeNode parentNode=SearchParent(node,value);
		
		if(targetNode.left==null&&targetNode.right==null) {//如果targetNode是叶子节点
			if(parentNode.left!=null&&parentNode.left.data==targetNode.data){//如果target是parent的左子树
				parentNode.left=null;
			}else if(parentNode.right!=null&&parentNode.right.data==targetNode.data) {//如果target是parent的右子树
				parentNode.right=null;
			}
		}
		else if(targetNode.left!= null && targetNode.right!=null) {//如果targetNode有两个子节点
			int minValue = delRightTreeMin(targetNode.right); //找右子树的最小值
			delete(targetNode.right,minValue);
			targetNode.data = minValue;//互换最小值
		}
		else { //只有一个子节点的节点
			 if(targetNode.left !=null){ //当前要删除的节点有左子树
					  if(parentNode.left.data == targetNode.data){ //删除的节点是父节点的左子树
						  parentNode.left = targetNode.left;
					  }else {//删除的节点是父节点的右子树
						  parentNode.right = targetNode.left;
					  }
			 }
			 else {//当前要删除的节点有右子树
				 if(parentNode.left.data == targetNode.data){  //删除的节点是父节点的左子树
					 parentNode.left = targetNode.right;
	             }else {//删除的节点是父节点的右子树
	                 parentNode.right = targetNode.right;
	             }
			 }
		}				
	}

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

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

相关文章

git pull error: cannot lock ref

Git: cannot lock ref ‘refs/remotes/origin/feature/xxx’: refs/remotes/origin/feature/xxx/car’ exists; cannot create refs/remotes/origin/feature/xxx git remote prune origin重新整理服务端和本地的关联关系即可

树与图深度优先遍历——acwing

题目一&#xff1a;树的重心 846. 树的重心 - AcWing题库 分析 采用暴力枚举&#xff0c;试探每个点&#xff0c;除去之后&#xff0c;连通分量最大值是多少&#xff0c; 各个点的最大值找最小的 因为可以通过 dfs 来得到 根u以下点数&#xff0c;以及可以求各分树的点数&am…

ultralytics-YOLOv11的目标检测解析

1. Python的调用 from ultralytics import YOLO import os def detect_predict():model YOLO(../weights/yolo11n.pt)print(model)results model(../ultralytics/assets/bus.jpg)if not os.path.exists(results[0].save_dir):os.makedirs(results[0].save_dir)for result in…

图形开发基础之在WinForms中使用OpenTK.GLControl进行图形绘制

前言 GLControl 是 OpenTK 库中一个重要的控件&#xff0c;专门用于在 Windows Forms 应用程序中集成 OpenGL 图形渲染。通过 GLControl&#xff0c;可以轻松地将 OpenGL 的高性能图形绘制功能嵌入到传统的桌面应用程序中。 1. GLControl 的核心功能 OpenGL 渲染上下文&…

Facebook广告文案流量秘诀

Facebook 广告文案是制作有效 Facebook 广告的关键方面。它侧重于伴随广告视觉元素的文本内容。今天我们的博客将深入探讨成功的 Facebook 广告文案的秘密&#xff01; 一、广告文案怎么写&#xff1f; 正文&#xff1a;这是帖子的正文&#xff0c;出现在您姓名的正下方。它可…

java面向对象实验——扫雷+24点

扫雷 窗口绘制&#xff1a; GameWin package com.sxt;import javax.swing.*;public class GameWin extends JFrame {void launch(){this.setVisible(true);this.setSize(500, 500);this.setLocationRelativeTo(null);this.setTitle("SWE23070扫雷游戏");this.setD…

Ubuntu24安装 python3-mysql.connector

正确命令 sudo apt install python3-mysql.connector说明 网络上已有的文章Python版本和Ubuntu版本旧&#xff0c;命令不生效。

【西门子PLC.博途】——在S71200里写时间设置和读取功能块

之前我们在这篇文章中介绍过如何读取PLC的系统时间。我们来看看在西门子1200里面有什么区别。同时也欢迎关注gzh。 我们在S71200的帮助文档中搜索时间后找到这个数据类型 在博途中他是一个结构体&#xff0c;具体为 然后我们再看看它带的读取和写入时间块 读取时间&#xff1…

如何搭建智慧工厂?IOT+AI:赋能未来制造业灯塔工厂建设

在当今数字化和智能化的浪潮中&#xff0c;传统制造业正经历着前所未有的变革。智慧工厂作为智能制造的核心内容&#xff0c;正逐步成为未来制造业的发展趋势。本文将深入探讨智慧工厂的搭建过程&#xff0c;以及IoT&#xff08;物联网&#xff09;和AI&#xff08;人工智能&am…

内存图及其画法

所有的文件都存在硬盘上&#xff0c;首次使用的时候才会进入内存 进程&#xff1a;有自己的Main方法&#xff0c;并且依赖自己Main运行起来的程序。独占一块内存区域&#xff0c;互不干扰。内存中有一个一个的进程。 操作系统只认识c语言。操作系统调度驱动管理硬件&#xff0…

Linux下,用ufw实现端口关闭、流量控制(二)

本文是 网安小白的端口关闭实践 的续篇。 海量报文&#xff0c;一手掌握&#xff0c;你值得拥有&#xff0c;让我们开始吧&#xff5e; ufw 与 iptables的关系 理论介绍&#xff1a; ufw&#xff08;Uncomplicated Firewall&#xff09;是一个基于iptables的前端工具&#xf…

Python使用Selenium自动实现表单填写之蛇年纪念币蛇钞预约(附源码,源码有注释解析,已测试可用

Python实现纪念币预约自动填写表单 声明:本文只做技术交流,不可用代码为商业用途,文末有源码下载,已测试可用。 Part 1 配置文件改写(源码 有详细的注释说明 读取配置文件,自己组数据库,录入信息 配置文件 Part 2 主函数 每一期的xpath路径都不一样 所以需要提前去网站…

内存管理面试常问

为什么要有虚拟内存&#xff1f; 虚拟内存 如果你是电⼦相关专业的&#xff0c;肯定在⼤学⾥捣⿎过单⽚机。 单⽚机是没有操作系统的&#xff0c;所以每次写完代码&#xff0c;都需要借助⼯具把程序烧录进去&#xff0c;这样程序才能跑起来。 另外&#xff0c; 单⽚机的 CPU …

插入排序⁻⁻⁻⁻直接插入排序希尔排序

引言 所谓的排序&#xff0c;就是使一串记录按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 常见的排序算法有&#xff1a; 今天我们主要学习插入排序的直接插入排序和希尔排序。 直接插入排序 什么是直接插入排序&#xff1f; 直接插入排序其…

基于Springboot + Vue开发的飞驰驾校预约学习平台(项目源码 + lw)

一、功能介绍 飞驰驾校预约学习平台包含管理员、教练、用户三个角色以及前后台系统。 主要功能 前台系统功能 首页展示、理论考试、教练信息、教练预约、学习资料、学习视频观看、用户留言、公告信息展示、个人中心信息管理 后台系统功能 管理员或用户登录成功后&#xff0c…

【vivado】时序报告--best时序和worst时序

利用vivado进行开发时&#xff0c;生成best时序报告和worst时序报告。 best时序报告 slow选择min_max&#xff0c;fast选择none。 worst时序报告 fast选择min_max&#xff0c;slow选择none。

深度学习GPU显卡4060ti与4060有什么区别?又与游戏显卡有什么区别?

深度学习GPU显卡4060 Ti与4060的区别 &#xff1a; 性能差异 &#xff1a; 4060 Ti : 4060 Ti通常比4060更强大&#xff0c;具有更多的CUDA核心和更高的显存带宽&#xff0c;因此在计算密集型任务&#xff08;如深度学习训练和推理&#xff09;中表现更好。其显卡核心频率、CUD…

李飞飞:Agent AI 多模态交互的前沿探索

发布于:2024 年 11 月 27 日 星期三 北京 #RAG #李飞飞 #Agent #多模态 #大模型 Agent AI在多模态交互方面展现出巨大潜力,通过整合各类技术,在游戏、机器人、医疗等领域广泛应用。如游戏中优化NPC行为,机器人领域实现多模态操作等。然而,其面临数据隐私、偏见、可解释性…

leetcode 3001. 捕获黑皇后需要的最少移动次数 中等

现有一个下标从 1 开始的 8 x 8 棋盘&#xff0c;上面有 3 枚棋子。 给你 6 个整数 a 、b 、c 、d 、e 和 f &#xff0c;其中&#xff1a; (a, b) 表示白色车的位置。(c, d) 表示白色象的位置。(e, f) 表示黑皇后的位置。 假定你只能移动白色棋子&#xff0c;返回捕获黑皇后…

bash命令缓存导致命令执行失败的问题

1、问题背景 为了修复老版本 vsftpd 的安全漏洞&#xff0c;需要把生产环境上 vsftpd 版本升级到 vsftpd-3.0.5&#xff0c;因为直接使用 rpm 包的方式进行升级还涉及到下层依赖包的升级(生产环境上的依赖包版本不能随意变更&#xff0c;可能会影响其他上层应用)&#xff0c;所…