数据结构学习--Java删除二叉树节点

摘要:
=value){//进行比较,比较查找值和当前节点的大小if{current=current.leftChild;}else{current=current.rightChild;}if{returnnull;}}returncurrent;}/***删除节点*/publicbooleandelete{//引用当前节点,从根节点开始Nodecurrent=root;//应用当前节点的父节点Nodeparent=root;//是否为左节点booleanisleftChild=true;while(current.data!=delNode.rightChild){//successorParent.leftChild=successor.rightChild;//将删除的节点的整个右子树挂载到中继节点的右子树上successor.rightChild=delNode.rightChild;}returnsuccessor;}/***前序遍历*/publicvoidfrontOrder{if(localNode!

想了半天,是真的不好想(手动捂脸)

三种情况需要考虑:

1、该节点是叶子节点,没有子节点

要删除叶节点,只需要改变该节点的父节点的引用值,将指向该节点的引用设置为null就可以了。

数据结构学习--Java删除二叉树节点第1张

2、该节点有一个子节点

改变父节点的引用,将其直接指向要删除节点的子节点。

数据结构学习--Java删除二叉树节点第2张

3、该节点有两个子节点

要删除有两个子节点的节点,就需要使用它的中序后继来替代该节点。

数据结构学习--Java删除二叉树节点第3张

代码

package com.example.deer;
public class Tree {
//根节点
public Node root;
/**
* 插入节点
* @param value
*/
public void insert(long value,String sValue){
//封装节点
Node newNode = new Node(value,sValue);
//引用当前节点
Node current = root;
//引用父节点
Node parent;
//如果root为null,也就是第一次插入的时候
if(root == null){
root = newNode;
return;
}else{
while (true){
//父节点指向当前节点
parent = current;
//如果当前指向的节点数据比插入的要大,则向左走
if(current.data > value){
current = current.leftChild;
if(current == null){
parent.leftChild = newNode;
return;
}
}else{
current = current.rightChild;
if(current == null){
parent.rightChild = newNode;
return;
}
}
}
}
}
/**
* 查找节点
*/
public Node find(long value){
//引用当前节点,从根节点开始
Node current = root;
//循环,只要查找值不等于当前节点的数据项
while(current.data != value){
//进行比较,比较查找值和当前节点的大小
if(current.data > value){
current = current.leftChild;
} else {
current = current.rightChild;
}
if(current == null){
return null;
}
}
return current;
}
/**
* 删除节点
*/
public boolean delete(long value){
//引用当前节点,从根节点开始
Node current = root;
//应用当前节点的父节点
Node parent = root;
//是否为左节点
boolean isleftChild = true;
while(current.data != value){
parent = current;
//进行比较,比较查找值和当前节点的大小
if(current.data > value){
current = current.leftChild;
isleftChild = true;
} else {
current = current.rightChild;
isleftChild = false;
}
if(current == null){
return false;
}
}
//删除叶子节点,也就是该节点没有子节点
if(current.leftChild == null && current.rightChild == null){
if(current == root){
root = null;
}else if(isleftChild){//如果它是父节点的左子节点
parent.leftChild = null;
}else{
parent.rightChild = null;
}
}else if (current.rightChild == null){
if(current == root){
root = current.leftChild;
}else if(isleftChild){
parent.leftChild = current.leftChild;
}else{
parent.rightChild = current.leftChild;
}
}else if (current.leftChild == null){
if(current == root){
root = current.rightChild;
}else if(isleftChild){
parent.leftChild = current.rightChild;
}else{
parent.rightChild = current.rightChild;
}
} else {
Node successor = getSuccessor(current);
if(current == root){
root = successor;
} else if(isleftChild) {
parent.leftChild = successor;
}else{
parent.rightChild = successor;
}
successor.leftChild = current.leftChild;
}
return true;
}
/**
* 寻找中继节点
* @param delNode
* @return
*/
public Node getSuccessor(Node delNode){
Node successor = delNode;
Node successorParent = delNode;
Node current = delNode.rightChild;
while(current != null){
successorParent = successor;
successor = current;
current = current.leftChild;
}
if(successor != delNode.rightChild){
//
successorParent.leftChild = successor.rightChild;
//将删除的节点的整个右子树挂载到中继节点的右子树上
successor.rightChild = delNode.rightChild;
}
return successor;
}
/**
* 前序遍历
*/
public void frontOrder(Node localNode){
if(localNode != null){
//访问根节点
System.out.println(localNode.data + "," + localNode.sData);
//前序遍历左子树
frontOrder(localNode.leftChild);
//前序遍历右子树
frontOrder(localNode.rightChild);
}
}
/**
* 中序遍历
*/
public void inOrder(Node localNode){
if(localNode != null){
//中序遍历左子树
inOrder(localNode.leftChild);
//访问根节点
System.out.println(localNode.data + "," + localNode.sData);
//中序遍历右子树
inOrder(localNode.rightChild);
}
}
/**
* 后序遍历
*/
public void afterOrder(Node localNode){
if(localNode != null){
//后序遍历左子树
afterOrder(localNode.leftChild);
//后序遍历右子树
afterOrder(localNode.rightChild);
//访问根节点
System.out.println(localNode.data + "," + localNode.sData);
}
}
}

免责声明:文章转载自《数据结构学习--Java删除二叉树节点》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇可执行二进制文件的形成过程与简单调试好代码是管出来的——使用GitHub实现简单的CI/CD下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

node多版本切换

一、【NVM】 NVM (Node Version Manager): Nodejs的版本管理工具早期的nvw只支持Linux 和Mac,而window用户较多使用的是nvmw。但最近由于重装系统偶然发现已有更新nvm支持window,而且快捷方便,不需要设置环境变量。 二、【步骤】 如果已经安装过node版本,请先自行卸载,这一步很重要!!! 卸载现有n...

NodeJS、NPM安装配置与测试步骤(windows版本)

1、windows下的NodeJS安装是比较方便的(v0.6.0版本之后,支持windows native),只需要登陆官网(http://nodejs.org/),便可以看到首页的“INSTALL”按钮,直接点击就会自动下载安装了。 2、安装过程基本直接“NEXT”就可以了。(windows的安装msi文件在过程中会直接添加path的系统变量,变量值是...

002.使用kubeadm安装kubernetes 1.17.0

一 环境准备 1.1 环境说明 master      192.168.132.131      docker-server1 node1       192.168.132.132      docker-server2 node2       192.168.132.133      docker-server3 1.2 docker版本 [root@...

pm2用法详解+ecosystem.config

对于后台进程的管理,常用的工具是crontab,可用于两种场景:定时任务和常驻脚本。关于常驻脚本,今天介绍一款更好用的工具:pm2,基于nodejs开发的进程管理器,适用于后台常驻脚本管理,同时对node网络应用有自建负载均衡功能。官方的说法,pm2是一个带有负载均衡功能的Node应用的进程管理器,个人认为,并不准确,因为pm2支持多种语言,只是对于除no...

Redis Zset类型跳跃表算法实现(JAVA)

Redis 有序集合类型(zset) 底层核心实现的机制就是跳跃表   最近公司搞了技术分享的活动,正好快到我了,最近在研究Redis就说说redis实现的原理吧. 发现还是晚上脑子比较好使,建议看代码时候边看边画图 推荐画图工具 http://draw.io/ 首先定义一个双向链表的类 双向链表的流程图  跳跃表的结构图 跳跃表查找的过程 跳跃...

k8s-更换证书(apiserver新添加了VIP)

关键简略步骤 修改apiserver.csr.json文件,把VIP加进去.通过cfssl工具重新生成证书,然后将新证书把旧的证书给替换掉 然后node节点一般需要修改三个文件 ./config ./kubelet.kubeconfig ./kube-proxy.kubeconfig master节点重启apiserver,node节点重启kube...