当前位置:网站首页>删除二叉搜索树中的节点附图详解
删除二叉搜索树中的节点附图详解
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
- Tutorial on the use of Huawei cloud modelarts (with detailed illustrations)
- Dynamic programming stock problem comparison
- Weima, which is going to be listed, still can't give Baidu confidence
- Pytorch深度学习之环境搭建
- 大规模服务异常日志检索
- 高中物理:力、物体和平衡
- 庆贺!科蓝SUNDB与中创软件完成七大产品的兼容性适配
- 超标量处理器设计 姚永斌 第5章 指令集体系 摘录
- [proteus simulation] printf debugging output example based on VSM serial port
猜你喜欢
DB engines database ranking in July 2022: Microsoft SQL Server rose sharply, Oracle fell sharply
[unity ugui] scrollrect dynamically scales the grid size and automatically locates the middle grid
CocosCreator事件派发使用
7 RSA Cryptosystem
【Hot100】32. 最长有效括号
Recast of recastnavigation
爬虫初级学习
如何提高开发质量
Self reflection of a small VC after two years of entrepreneurship
Weima, which is going to be listed, still can't give Baidu confidence
随机推荐
shell脚本的替换功能实现
Achieve animation effect through event binding
TCP两次挥手,你见过吗?那四次握手呢?
【系统盘转回U盘】记录系统盘转回U盘的操作
Oppo Xiaobu launched Obert, a large pre training model, and promoted to the top of kgclue
[HCIA continuous update] overview of WLAN workflow
为啥有些线上演唱会总是怪怪的?
【Hot100】32. 最长有效括号
mysql5.7安装教程图文详解
【209】go语言的学习思想
Rainfall warning broadcast automatic data platform bwii broadcast warning monitor
Interpretation of data security governance capability evaluation framework 2.0, the fourth batch of DSG evaluation collection
How to test MDM products
With the stock price plummeting and the market value shrinking, Naixue launched a virtual stock, which was deeply in dispute
CocosCreator事件派发使用
Five thousand words to clarify team self-organization construction | Liga wonderful talk
【Hot100】31. 下一个排列
设置窗体透明 隐藏任务栏 与全屏显示
DB-Engines 2022年7月数据库排行榜:Microsoft SQL Server 大涨,Oracle 大跌
uni-app与uviewUI实现仿小米商城app(附源码)