当前位置:网站首页>删除二叉搜索树中的节点附图详解
删除二叉搜索树中的节点附图详解
2022-07-04 16:24:00 【风能保暖内裤】
文章目录
二叉搜索树的删除较为繁琐,但是静下心来相信很快就能吸收!主要分为两步:首先是查找待删除节点,然后针对这个节点进行删除。
我们用cur变量搜索,用parent变量表示curr的双亲结点
搜索待删除节点
搜索不是这篇文章的重点,我们直接上代码
public boolean delete(int key) {
// wirte code here,主要分为三种情况
Node parent = null;
Node cur = root;//cur负责找到需要删除的节点
while (cur != null) {
if (cur.key < key) {
parent = cur;
cur = cur.right;
} else if (cur.key > key) {
parent = cur;
cur = cur.left;
} else {
//△到这里,我们就找到了待删除节点,即cur
deleteNode(parent, cur);
//deleteNode方法就是删除cur节点
return true;
}
}
return false;
}
注意:到上面代码的三角形处,我们就找到了待删除节点cur
正文(删除cur节点)
我们分为三种情况:(cur节点就是待删除节点,parent是cur的双亲结点,下文不赘述)
- cur.left = null;
- cur.right = null;
- cur.left != null && cur.right != null;
情况1:cur.left = null
这次情况又分为3种情况
- cur 是 根节点
- cur 是 parent 的左孩子
- cur 是 parent 的右孩子
① cur 为根节点
这种情况下,我们直接让root = root.right即可

② cur 为 parent 的左孩子
如图,我们让parent.left = cur.right即可

③ cur 为 parent 的右孩子
如图,我们让parent.right = cur.right即可
情况2:cur.right = null
- 情况 2 和情况 1 思路基本上是一样的,我们再重复一次巩固一下
- cur 是 根节点
- cur 是 parent 的左孩子
- cur 是 parent 的右孩子
① cur 为根节点
同理,只需root = root.left即可

② cur 为 parent 的左孩子
如图,我们让parent.left = cur.left
③ cur 为 parent 的右孩子
如图,我们让parent.right = cur.left
情况3:cur.left != null && cur.right != null
核心思想:在 cur 的右子树中找到值最小的节点,然后将该节点值赋给 cur ,再将该最小节点删除
- 所以就一共有两个步骤:① 找 cur 右子树最小节点,并将该最小值赋给cur ② 删除这个最小节点
步骤①
先定义 target = cur.right,再让 targetParent 为 target 的双亲结点
最终:让 target 指向 cur 右子树的最小节点,让 targetParent 指向 target的双亲
以下 ↓ 代码是让 target 指向 cur 右子树的最小节点
Node target = cur.right;//找到cur右子树中的最小节点,替换cur节点,并且删除这个最小节点
Node targetParent = cur; //target节点的双亲结点
while (target.left != null) {
//找到右子树的最小节点
targetParent = target;
target = target.left;
}
然后再赋值:cur.key = target.key;,如图
步骤②
到了这一步,我们的任务就只剩删除 target 节点了,这时再分为两种情况,也比较好理解了
- target == targetParent.left
- tartget == targetParent.right
情况1 :仅需targetParent.left = target.right
情况2:仅需targetParent.right = target.right
完成!
删除 cur 节点代码
private void deleteNode(Node parent, Node cur) {
//至此,cur指向待删除的节点
if (cur.left == null) {
//情况1,如果左孩子为空
if (cur == root) {
root = cur.right;
} else if (parent.left == cur) {
parent.left = cur.right;
} else {
parent.right = cur.right;
}
} else if (cur.right == null) {
//情况2,如果右孩子为空
if (cur == root) {
root = cur.left;
} else if (parent.left == cur) {
parent.left = cur.left;
} else {
parent.right = cur.left;
}
} else {
//情况3,如果左右孩子都不为空
Node target = cur.right;//找到cur右子树中的最小节点,替换cur节点值,并且删除这个最小节点
Node targetParent = cur; //target节点的双亲结点
while (target.left != null) {
//找到右子树的最小节点
targetParent = target;
target = target.left;
}
cur.key = target.key; //覆盖cur值
if (target == targetParent.left) {
targetParent.left = target.right;
} else {
targetParent.right = target.right;
}
}
}
全代码
public boolean delete(int key) {
// wirte code here,主要分为三种情况
Node parent = null;
Node cur = root;//cur负责找到需要删除的节点
while (cur != null) {
if (cur.key < key) {
parent = cur;
cur = cur.right;
} else if (cur.key > key) {
parent = cur;
cur = cur.left;
} else {
deleteNode(parent, cur);
return true;
}
}
return false;
}
private void deleteNode(Node parent, Node cur) {
//至此,cur指向待删除的节点
if (cur.left == null) {
//如果左孩子为空
if (cur == root) {
root = cur.right;
} else if (parent.left == cur) {
parent.left = cur.right;
} else {
parent.right = cur.right;
}
} else if (cur.right == null) {
//如果右孩子为空
if (cur == root) {
root = cur.left;
} else if (parent.left == cur) {
parent.left = cur.left;
} else {
parent.right = cur.left;
}
} else {
//如果左右孩子都不为空
Node target = cur.right;//找到cur右子树中的最小节点,替换cur节点,并且删除这个最小节点
Node targetParent = cur; //target节点的双亲结点
while (target.left != null) {
//找到右子树的最小节点
targetParent = target;
target = target.left;
}
cur.key = target.key; //覆盖
if (target == targetParent.left) {
targetParent.left = target.right;
} else {
targetParent.right = target.right;
}
}
}
边栏推荐
- Cann operator: using iterators to efficiently realize tensor data cutting and blocking processing
- [daily question] 871 Minimum refueling times
- 2022年DCMM认证全国各地补贴政策汇总
- 设置窗体透明 隐藏任务栏 与全屏显示
- Is it science or metaphysics to rename a listed company?
- mysql5.7安装教程图文详解
- 无心剑中译伊丽莎白·毕肖普《一门技艺》
- Superscalar processor design yaoyongbin Chapter 7 register rename excerpt
- Face_recognition人脸识别之考勤统计
- 【HCIA持续更新】广域网技术
猜你喜欢

CocosCreator事件派发使用

要上市的威马,依然给不了百度信心

“在越南,钱就像躺在街上”

估值900亿,超级芯片IPO来了

Five thousand words to clarify team self-organization construction | Liga wonderful talk

机器学习概念漂移检测方法(Aporia)

就在今天丨汇丰4位专家齐聚,共讨银行核心系统改造、迁移、重构难题

Rainfall warning broadcast automatic data platform bwii broadcast warning monitor

【HCIA持续更新】网络管理与运维

明星开店,退,退,退
随机推荐
Initial experience of domestic database tidb: simple and easy to use, quick to start
Make a grenade with 3DMAX
12 - explore the underlying principles of IOS | runtime [isa details, class structure, method cache | t]
国产数据库TiDB初体验:简单易用,快速上手
“在越南,钱就像躺在街上”
uni-app与uviewUI实现仿小米商城app(附源码)
[test development] software testing - Basics
使用3DMAX制作一枚手雷
Why are some online concerts always weird?
Is it science or metaphysics to rename a listed company?
Oppo Xiaobu launched Obert, a large pre training model, and promoted to the top of kgclue
The controversial line of energy replenishment: will fast charging lead to reunification?
【Hot100】31. Next spread
明星开店,退,退,退
DB engines database ranking in July 2022: Microsoft SQL Server rose sharply, Oracle fell sharply
New technology releases a small program UNIPRO to meet customers' mobile office scenarios
大规模服务异常日志检索
Talk about seven ways to realize asynchronous programming
正则表达式
为啥有些线上演唱会总是怪怪的?