java有序二叉树的删除节点方式

 更新时间:2024年12月17日 08:57:34   作者:Sshm_666  
文章描述了在二叉树中删除节点的三种情况及其对应的操作步骤,通过递归找到节点及其父节点,并根据节点的子树情况(无子树、单子树、双子树)进行相应的删除操作,文章还提供了一个测试类来验证删除操作的正确性

java有序二叉树的删除节点

删除节点时会有三种可能

1、删除的节点为叶子节点

我们如果删除为叶子节点,则步骤应该是:

1)先找到要删除的叶子节点

2)再找到要删除节点的父节点(考虑是否有父节点)

3)找到删除的节点是父节点的左子树还是右子树

4)根据前面的情况进行删除

2、删除的节点只有一个子树

步骤:

1)先找到要删除的节点

2)再找到要删除节点的父节点(考虑是否有父节点)

3)确定删除的节点是有左子树还是有右子树

4)找到删除的节点是父节点的左子树还是右子树

5)根据前面的情况进行删除

3、删除的节点有两个子树

步骤:

1)先找到要删除的节点

2)再找到要删除节点的父节点(考虑是否有父节点)

3)找到删除节点右子树当中最小的或左子树最大的节点

4)将3)找到的这个节点的值替换掉要删除的节点的值

5)删除找到的3)

通过上面步骤它们都有一个共同特点就是需要找到删除的节点和要删除节点的父节点,所以我们可以把这两个找节点都写成方法:

找到删除节点代码如下(通过递归的方式找到要删除节点位置并记录下来):

//找到要删除的节点
	public TreeNode searchDelnode(TreeNode node,Integer val) {
		if(node==null) {
			return null;
		}
		if(node.val==val) {
			return node;
		}else if(val>node.val){
			if(node.rightNode==null) {
				return null;
			}
			return searchDelnode(node.rightNode, val);
		}else {
			if(node.leftNode==null) {
				return null;
			}
			return searchDelnode(node.leftNode, val);
		}
	}

找被删除节点的父节点代码如下所示:

//找到要删除节点的父节点
	public TreeNode searchDelpartent(TreeNode node,Integer val) {
		if(node==null) {
			return null;
		}
		if((node.leftNode!=null&&node.leftNode.val==val)||(node.rightNode!=null&&node.rightNode.val==val)) {
			return node;
		}else {
			if(node.leftNode!=null&&val<node.val) {
				return searchDelpartent(node.leftNode, val);
			}else if(node.rightNode!=null&&val>node.val){
				return searchDelpartent(node.rightNode, val);
			}else {
				return null;
			}
		}
	}

我们可以根据以上步骤写删除方法代码:

//二叉树删除节点
	public void del(TreeNode node,Integer val) {
		if(node==null) {
			return;
		}
		//1.找到要删除的节点
		TreeNode targetNode=searchDelnode(node, val);
		//2.没有找到要删除的节点
		if(targetNode==null) {
			return;
		}
		//3.找到要删除节点的父节点
		TreeNode parentNode=searchDelpartent(node, val);
		if(node.rightNode==null&&node.leftNode==null) {
			root=null;
			return;
		}
		if(parentNode==null&&(targetNode.rightNode!=null||targetNode.leftNode!=null)) {
			int min=searchRightMin(targetNode.rightNode);
			targetNode.val=min;
			return;
		}
		if(targetNode.leftNode==null&&targetNode.rightNode==null) {
			if(parentNode.rightNode!=null&&parentNode.rightNode.val==targetNode.val) {
				parentNode.rightNode=null;
			}else if(parentNode.leftNode!=null&&parentNode.leftNode.val==val){
				parentNode.leftNode=null;
			}
		}else if(targetNode.leftNode!=null&&targetNode.rightNode!=null) {
//在删除节点由左右两个子树时,我们选择找删除节点右子树的最小值,我们可以写一个方法,在这个方法里不仅找到最小值,并把这个位置的元素进行删除
			int min=searchRightMin(targetNode.rightNode);
			targetNode.val=min;
		}else {
			if(targetNode.rightNode!=null) {
				if(parentNode.rightNode.val==targetNode.val) {
					parentNode.rightNode=targetNode.rightNode;
				}else {
					parentNode.leftNode=targetNode.rightNode;
				}
			}else{
				if(targetNode.rightNode.val==targetNode.val) {
					parentNode.rightNode=targetNode.leftNode;
				}else {
					parentNode.leftNode=targetNode.leftNode;
				}
			}
		}
	}

在删除节点由左右两个子树时,我们选择找删除节点右子树的最小值,我们可以写一个方法,在这个方法里不仅找到最小值,并把这个位置的元素进行删除

代码如下:

public int searchRightMin(TreeNode node) {
		TreeNode temp=node;
		while(temp.leftNode!=null) {
			temp=temp.leftNode;
		}
		del(root, temp.val);
		return temp.val;
	}
}

写一个测试类进行测试:

public class Test {
	public static void main(String[] args) {
		BinaryTree binaryTree=new BinaryTree();
		binaryTree.insert(1);
		binaryTree.insert(2);
		binaryTree.insert(3);
		binaryTree.insert(4);
		binaryTree.insert(5);
		binaryTree.insertDigui(6, binaryTree.root);
		binaryTree.insertDigui(7, binaryTree.root);
		binaryTree.insertDigui(8, binaryTree.root);
		binaryTree.insertDigui(9, binaryTree.root);
		binaryTree.del(binaryTree.root, 2);
		binaryTree.Order();
		System.out.println();
		binaryTree.startErgodic(binaryTree.root);
		System.out.println();
		binaryTree.midErgodic(binaryTree.root);
		System.out.println();
		binaryTree.endErgodic(binaryTree.root);
	}
}

结果如下图所示:

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • springboot启动mongoDB报错之禁用mongoDB自动配置问题

    springboot启动mongoDB报错之禁用mongoDB自动配置问题

    这篇文章主要介绍了springboot启动mongoDB报错之禁用mongoDB自动配置问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • 总结一些Java常用的加密算法

    总结一些Java常用的加密算法

    今天给大家带来的是关于Java的相关知识,文章围绕着Java加密算法展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • 实例讲解Java批量插入、更新数据

    实例讲解Java批量插入、更新数据

    这片文章介绍了一个Java批量添加数据,多个字段同时添加多条数据具体实例,面向的是Oracle数据库,需要的朋友可以参考下
    2015-07-07
  • mybatis-plus实现多表查询的示例代码

    mybatis-plus实现多表查询的示例代码

    MyBatis-Plus提供了多种方式实现多表查询,包括使用注解、MyBatis-PlusJoin扩展和XML配置文件,每种方法都有其适用场景和优势,本文就来具体介绍一下,感兴趣的可以了解一下
    2024-11-11
  • Java实现批量下载选中文件功能

    Java实现批量下载选中文件功能

    这篇文章主要介绍了Java实现批量下载选中文件功能,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-11-11
  • 如何利用postman完成JSON串的发送功能(springboot)

    如何利用postman完成JSON串的发送功能(springboot)

    这篇文章主要介绍了如何利用postman完成JSON串的发送功能(springboot),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Java数据结构之图的原理与实现

    Java数据结构之图的原理与实现

    图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。本文将详细介绍图的原理及其代码实现,需要的可以参考一下
    2022-01-01
  • 模仿Spring手写一个简易的IOC

    模仿Spring手写一个简易的IOC

    这篇文章主要介绍了模仿Spring手写一个简易的IOC,帮助大家更好的理解和学习spring框架,感兴趣的朋友可以了解下
    2020-11-11
  • 使用IDEA创建SpringBoot项目

    使用IDEA创建SpringBoot项目

    本文详细介绍了使用SpringBoot创建项目,包含配置、启动、开发环境配置等,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-12-12
  • Java实现企业员工管理系统

    Java实现企业员工管理系统

    这篇文章主要为大家详细介绍了Java实现企业员工管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02

最新评论