题目描述
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
首先找到需要删除的节点; 如果找到了,删除它。 示例 1:
输入:root = [5,3,6,2,4,null,7], key = 3
输出:[5,4,6,2,null,null,7]
解释:给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。
一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。
另一个正确答案是 [5,2,6,null,4,null,7]。
思路
节点分为五种情况:
- 没有找到目标节点
- 找到了目标节点:
- 目标节点为叶子节点,return——>null
- 目标节点的左子树为null,右子树不为null return ——>右子树
- 目标节点左子树不为null,右子树为null,return——>左子树
- 目标节点的左右子树都不为null,找到右子树中的最小节点,将该节点的左子树赋值为目标节点的左子树,返回目标节点的右子树
代码
/**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/
function deleteNode(root: TreeNode | null, key: number): TreeNode | null {
// 终止条件
if(root==null){return root}
if(root.val==key){
if(root.left==null&&root.right==null){
return null
}else if(root.left!=null&&root.right==null){
return root.left;
}else if(root.left==null&&root.right!=null){
return root.right;
}else{
let curNode=root.right;
while(curNode.left){
curNode=curNode.left;
}
curNode.left=root.left;
return root.right;
}
}
//单层逻辑
if(root.val>key){
root.left=deleteNode(root.left,key);
}
else{
root.right=deleteNode(root.right,key);
}
return root;
};
总结
删除二叉搜索树的节点,要明确目标节点的几种情况,以及几种情况对应的操作。如有错误之处,欢迎大家留言指出。