题目描述:
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
首先找到需要删除的节点;
如果找到了,删除它。
来源:力扣(LeetCode)
思路:没有思路
最后的结果是,自己最容易理解的情况!
要记住的重要的点!
①使用有返回值的方法进行递归,免去了传入前一个几点的情况,直接用left,right分别接收,处理后的左右子树的根节点的情况!和59.中插入节点的操作类似!
② 带有左右子树的节点,可以有两个关键内容,前驱节点和后继节点;也就是将BST中序输出,当前节点紧挨着的两个节点!
当左右子树都不为空时,找到后继节点,替换掉要删除节点的值;再递归,删除后继节点!
在后继节点的删除中和之前的删除过程类似!
③对于左右子树全为空,直接返回null;此时null和上面的内容连起来,作为修改后的子树的根节点传给上层的节点!
左右各有一个null,将另一个返回上去就好!
代码:
1)递归实现
class Solution {
//插入和删除,都用到了返回值为节点的 方法!
public TreeNode deleteNode(TreeNode root, int key) {
return delete(root,key);
}
//方法返回的都是 子树的根节点
TreeNode delete(TreeNode root,int key){
//这条路径走到头,没有删除
if(root == null) return null;
//要删除的在左子树,左子节点拿到左子树上删除之后返回回来的 根节点
if(root.val > key) root.left = delete(root.left,key);
//要删除的在 右子树
else if(root.val < key) root.right = delete(root.right,key);
//该节点就是要删除的节点
else{
//该节点还有多种情况
if(root.left == null && root.right == null) return null;//该节点是叶子节点,删除,返回给上一层的 本子树的根节点为null
else if(root.left != null && root.right == null) return root.left;
else if(root.left ==null && root.right != null) return root.right;
//此时左右子树都不为零
//有一个特殊操作!
//使用该节点的后继节点:也就是BST 中序输出,该节点的紧跟的节点
TreeNode temp = root.right;
//此处要使用temp.left进行判断!
while(temp.left != null){
temp = temp.left;
}
//此时的temp即后继节点
root.val = temp.val;//只修改值!
//再去把后继节点删除掉
root.right = delete(root.right,temp.val);
}
return root;
}
}