Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >排序二叉树-删除节点

排序二叉树-删除节点

作者头像
shengjk1
发布于 2020-06-28 03:14:11
发布于 2020-06-28 03:14:11
57700
代码可运行
举报
文章被收录于专栏:码字搬砖码字搬砖
运行总次数:0
代码可运行

我们已经了解了什么是排序二叉树以及排序二叉树的遍历和添加元素,现在我们一起来看一下,排序二叉树是如何删除元素的。

步骤
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
先找到要删除的节点 targetNode
找到要删除节点的父节点 parent
一、删除叶子节点
1.确定 targetNoe 是 parent 的左子节点还是右子节点
2.根据前面的情况来对应删除
parent.left=null.
parent.right=null
二、删除只有一颗子树的节点
1.确定 targetNode 的子节点是右子节点还是左子节点
2.确定 targetNode 是 parent 的左子节点还是右子节点
3.对应删除
三、删除有两颗子树的节点
1.从 targetNode 的右子树找到最小的节点
2.用一个临时变量,将最小节点的值保存 temp
3.删除最小节点
4.targetNode.value=temp
代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package xmht.datastructuresandalgorithms.datastructure.binarysortTree;

/**
 * @author shengjk1
 * @date 2020/6/15
 */
public class BinarySortTree {
	public static void main(String[] args) {
		int[] arr = {7, 3, 10, 12, 5, -1, 9};
		BinarySortTree1 binarySortTree = new BinarySortTree1();
		for (int i : arr) {
			binarySortTree.add(new Node(i));
		}
		
		System.out.println("中序遍历二叉树");
		binarySortTree.infixOrder();
		
		binarySortTree.delNode(3);
		
		System.out.println("删除之后====中序遍历二叉树");
		binarySortTree.infixOrder();
	}
}

class BinarySortTree1 {
	//
	private Node root;
	
	public void add(Node node) {
		if (this.root != null) {
			this.root.add(node);
		} else {
			root = node;
		}
	}
	
	//查找节点
	public Node search(int value) {
		if (root == null) {
			return null;
		} else {
			return root.search(value);
		}
	}
	
	//查找父节点
	public Node searchParent(int value) {
		if (root == null) {
			return null;
		} else {
			return root.searchParent(value);
		}
	}
	
	/**
	 * 返回以 node 为根节点的二叉排序树的最小节点的值
	 * 并删除以 node 为根节点的二叉排序树的最小节点
	 *
	 * @param node 传入节点
	 * @return 以 node 为根节点的二叉排序树的最小节点的值
	 */
	public int delRightTreeMin(Node node) {
		Node target = node;
		while (target.left != null) {
			target = target.left;
		}
		delNode(target.value);
		return target.value;
		
	}
	
	//删除节点
	public void delNode(int value) {
		if (root == null) {
			return;
		} else {
			//1.先找到要删除节点 targetNode
			Node targetNode = root.search(value);
			if (targetNode == null) {
				return;
			}
			//如果发现当前的二叉树只有一个节点
			if (root.left == null && root.right == null) {
				root = null;
				return;
			}
			
			//找到 targetNode 的 parentnode
			Node parentNode = searchParent(value);
			
			//1.如果删除的节点是叶子节点
			if (targetNode.right == null && targetNode.left == null) {
				if (parentNode.left != null && parentNode.left.value == value) {
					parentNode.left = null;
				} else {
					parentNode.right = null;
				}
				//删除有两颗子树的节点
			} else if (targetNode.left != null && targetNode.right != null) {
				int minVal = delRightTreeMin(targetNode.right);
				targetNode.value = minVal;
				//删除只有一颗子树的节点
			} else {
				//如果删除的节点只有左子树
				if (targetNode.left != null) {
					if (parentNode != null) {
						if (parentNode.left.value == value) {
							parentNode.left = targetNode.left;
							//targetNode 为 parent 的右节点
						} else {
							parentNode.right = targetNode.left;
						}
					} else {
						root = targetNode.left;
					}
				} else {
					if (parentNode != null) {
						if (parentNode.left.value == value) {
							parentNode.left = targetNode.right;
						} else {
							parentNode.right = targetNode.right;
						}
					} else {
						root = targetNode.right;
					}
				}
			}
		}
	}
	
	public void infixOrder() {
		if (this.root != null) {
			this.root.infixOrder();
		}
	}
	
	@Override
	public String toString() {
		return "BinarySortTree1{" +
				"root=" + root +
				'}';
	}
}

class Node {
	int value;
	Node left;
	Node right;
	
	public Node(int value) {
		this.value = value;
	}
	
	
	/**
	 * @param value 希望删除节点的值
	 * @return 有则返回否则返回null
	 */
	public Node search(int value) {
		if (value == this.value) {
			return this;
			//向左子树查找
		} else if (value < this.value) {
			if (this.left == null) {
				return null;
			}
			return this.left.search(value);
			
			//向右子树查找
		} else {
			if (this.right == null) {
				return null;
			}
			return this.right.search(value);
		}
	}
	
	//查找要删除节点的父节点
	
	/**
	 * @param value
	 * @return
	 */
	public Node searchParent(int value) {
		//如果当前节点就是要删除节点的父节点,就返回
		if ((this.left != null && this.left.value == value) ||
				(this.right != null && this.right.value == value)) {
			return this;
		} else {
			if (value < this.value && this.left != null) {
				return this.left.searchParent(value);
			} else if (value >= this.value && this.right != null) {
				return this.right.searchParent(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 infixOrder() {
		if (this.left != null) {
			this.left.infixOrder();
		}
		System.out.println(this);
		
		if (this.right != null) {
			this.right.infixOrder();
		}
	}
	
	
	@Override
	public String toString() {
		return "Node{" +
				"value=" + value +
				'}';
	}
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/06/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Oracle 审计失败的用户登陆(Oracle audit)
       对于在线交易系统,且Oracle用户在使用缺省的profile的情形下,多用户共享相同的数据库用户及密码,任意用户输入错误密码累计达到10次以上,其帐户会被自动锁定使得交易被迫临时终止将产生不小的损失。故有必要对那些失败的帐户登陆进行分析以预估是否存在恶意攻击等。Oracle提供了审计功能用于审计那些失败的Oracle用户登陆来进行风险评估。本文即是描述如何开启审计失败的用户登陆。本文不涉及审计的具体的描述信息,仅仅描述如何审计失败的用户登陆。详细完整的审计大家可以参考Oracle Database Security Guide。
Leshami
2018/08/13
1.8K0
等保测评2.0:Oracle安全审计
本篇文章主要说一说Oracle数据库安全审计控制点中b、c、d测评项的相关内容和理解,以及一些其它零碎的与等保相关的内容。
FB客服
2020/07/28
7.6K0
Oracle 10g安全加固(审计、监听密码)
Oracle 10g审计功能默认是关闭的。 需要注意开启审计功能必然会额外消耗一部分数据库性能,开启审计需要重启数据库生效。 具体的审计策略则需要根据项目实际要求自行配置。
Alfred Zhao
2019/05/24
9270
【DB笔试面试828】在Oracle中,什么是审计(Audit)?
审计(Audit)用于监视用户所执行的数据库操作,审计信息可存储于数据字典表,称为审计记录。审计记录存储在SYSTEM表空间中的SYS.AUD表中,可通过视图DBA_AUDIT_TRAIL查看。审计记录也可以存储在操作系统文件中(默认位置为ORACLE_BASE/admin/ORACLE_SID/adump/)。若审计表不存在,则可以通过脚本ORACLE_HOME/rdbms/admin/cataudit.sql来创建。
AiDBA宝典
2020/06/24
2.2K0
案例分享:关闭 Oracle 审计时遇到的 Bug 排查与解决
一重要的生产库长期以来就有各种问题,前段时间刚进行完 PSU190716 的更新,这两天查到发现审计功能对其性能有较大的影响,故客户要求关闭审计功能。我们便申请了三个小时的停机窗口,进行关闭审计的操作。心想改参数重启实例四十分钟就可以搞定的事,三个小时多多有余,因为数据量达五六十 T ,小伙伴都比较怕,只有我做了。以下涉及到实际的主机名、实例名均已替换为测试相关的,如不对应忽略即可。
JiekeXu之路
2020/05/12
1.9K0
由dual导致的一个潜在的监控问题(r7笔记第3天)
Oracle对于sys用户的审计是默认的操作,所以不管你开启了什么审计策略,sys的登录等操作都会记录下来,这也是Oracle的默认配置,可能他 们也没有料到有些应用可能把这个影响放大,毕竟频繁登录sys听起来是不现实的。但是放到自动化监控的部分,这个影响就会放大,可能有些功能还不够严谨, 存在一定的问题。 比如下面的这个场景,发现在审计目录下存在着一些细小的文件,生成时间也很紧凑,可见还是有一些操作很频繁的使用了sys,而且生成了意料之外的大批量审计日志文件。 $ ls -lrt|head -5 -rw
jeanron100
2018/03/16
6260
【常用命令】监视数据库的用户登录和注销会话信息
通过使用audit session whenever successful 命令,成功的连接会被审计。
SQLplusDB
2020/03/26
1.6K0
Oracle 主库rac + 备库rac 11.2.0.4的DG环境部署
各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~:
AiDBA宝典
2023/04/27
4.1K0
Oracle 主库rac + 备库rac 11.2.0.4的DG环境部署
Oracle告警日志里记录了“KILL SOFT -/-/-”会话被杀掉的信息
当由于空闲超时而手动或由PMON终止会话后手动执行alter system kill session时,将在警报日志中记录相关信息
AiDBA宝典
2023/09/08
5060
Oracle告警日志里记录了“KILL SOFT -/-/-”会话被杀掉的信息
手动清理Oracle审计记录
a、对于Oracle 11g,审计功能默认被开启,因此如果在必须启用的情况下应考虑性能影响; b、开启审计的情况下,建议将审计从system或sysaux表空间剥离,使用单独的表空间; c、对于历史审计日志的清除,应考虑清除期间所带来的性能影响; d、调用DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION这个过程已经开始了搬迁过程,如果审计日志很庞大,应考虑IO影响; e、审计日志的清除需要先设定归档,已归档的审计日志会被清理; f、也可以通过trunate table aud$ reuse storage以及deallocate非常规方式来处理。
Leshami
2018/08/13
1.7K0
EXP导出aud$报错EXP-00008,ORA-00904 解决
主题:EXP导出aud$报错EXP-00008,ORA-00904 解决 环境:Oracle 11.2.0.4 问题:在自己的测试环境,导出sys用户下的aud$表报错。
Alfred Zhao
2019/05/24
1.5K0
Oracle 常用命令大汇总
第一章:日志管理     1.forcing log switches     sql> alter system switch logfile;     2.forcing checkpoints     sql> alter system checkpoint;     3.adding online redo log groups     sql> alter database add logfile [group 4]     sql> ('/disk3/log4a.rdo','/di
阿新
2018/04/09
9430
2021年4月Oracle数据库补丁分析报告
编写此文档为了更好地指导Oracle补丁安装工作,细化工作任务,规范安装升级操作。
数据和云
2021/05/31
2.4K0
又一例SPFILE设置错误导致数据库无法启动
--========================================
Leshami
2018/08/07
7420
Oracle知识集锦:对Oracle数据库进行监控检查
execute dbbms_workload_repository.create_snapshot();
星哥玩云
2022/08/16
1.2K0
等保测评之Oracle关系型数据库安全加固实践指南
select ‘bgdrac’ database,t11.username,t11.default_tablespace tablespace_name,segment_size_in_GB,datafile_size_in_gb,tablespace_free_size_in_gb from (select username,default_tablespace from dba_users) t11 left join ( select nvl(t1.tablespace_name,t2.tablespace_name) tablespace_name,t1.size_in_GB datafile_size_in_GB,t2.size_in_GB segment_size_in_GB,t1.size_in_GB-t2.size_in_GB tablespace_free_size_in_GB from (select tablespace_name,sum(bytes)/1024/1024/1024 size_in_GB from dba_data_files group by tablespace_name) t1 full join (select tablespace_name,sum(bytes)/1024/1024/1024 size_in_GB from dba_segments group by tablespace_name) t2 on t2.tablespace_name=t1.tablespace_name) t22 on t22.tablespace_name=t11.default_tablespace where t11.default_tablespace<>’zlbfxt’;
全栈工程师修炼指南
2022/09/29
1.9K0
Oracle 10gR2 Dataguard搭建(非duplicate方式)
我的实验环境: 源生产库(主库): IP地址:192.168.1.30 Oracle 10.2.0.5 单实例
Alfred Zhao
2019/05/24
7460
单实例Primary快速搭建Standby RAC参考手册(19.16 ADG)
上述为这里我做为演示环境的基本规划。 本文作为step by step的快速指导手册,方便快速部署此类ADG环境。
Alfred Zhao
2023/03/06
4020
一线运维 DBA 五年经验常用 SQL 大全(二)
本文 SQL 及相关命令均是在运维工作中总结整理而成的,对于运维 DBA 来说可提高很大的工作效率,值得收藏。当然如果你全部能够背下来那就很牛逼了,如果不能,还是建议收藏下来慢慢看,每条 SQL 的使用频率都很高,肯定能够帮助到你。
JiekeXu之路
2021/03/15
9050
一线运维 DBA 五年经验常用 SQL 大全(二)
oracle11g dataguard安装实施
Oracle DataGuard 实施 1.环境准备 1.1 修改主备机hosts文件 vi /etc/hosts 128.160.11.84    wang 128.160.11.218  dg2 1.2 修改(添加)主备机listener.ora和tnsnames.ora文件 vi $ORACLE_HOME/network/admin/listener.ora SID_LIST_LISTENER =         (SID_LIST =           (SID_DESC =                 (SID_NAME = softdb)                 (ORACLE_HOME = /u01/app/oracle/product/11.2.0/db_1/)           )         ) LISTENER =   (DESCRIPTION_LIST =     (DESCRIPTION =       (ADDRESS = (PROTOCOL = TCP)(HOST = wang)(PORT = 1521))       (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))     )   ) ADR_BASE_LISTENER = /u01/app/oracle vi $ORACLE_HOME/network/admin/tnsnames.ora SOFTPRI =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = wang)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = softdb)     )   ) SOFTSTD =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = dg2)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = softdb)     )   ) 1.3 确定主备机parameter/control/data/log/archivelog file 的路径 audit_file_dest='/u01/app/oracle/admin/softdb/adump' 1.4 设置主库强制写日志 SQL> select force_logging from v$database; FOR --- NO SQL> alter database force logging; Database altered. SQL> select force_logging from v$database; FOR --- YES 1.5 设置主库归档模式 SQL> archive log list; SQL> shutdown immediate; SQL> startup mount; SQL> alter database archivelog; SQL> alter database open; SQL> archive log list; Database log mode              Archive Mode Automatic archival             Enabled Archive destination            /u01/app/oracle/product/11.2.0/db_1//dbs/arch Oldest online log sequence     175 Next log sequence to archive   177 Current log sequence           177 2. 产生用于建立Standby库的全备份集及控制文件 2.1 创建并修改主库参数文件pfile SQL> shutdown immediate; SQL> create pfile from spfile; 修改initsoftdb.ora vi $ORACLE_HOME/db
吹水老王
2022/05/17
8120
推荐阅读
相关推荐
Oracle 审计失败的用户登陆(Oracle audit)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验