450. 删除二叉搜索树中的节点 - 力扣(LeetCode)
针对要删除节点的子节点个数的不同,分三种情况来处理:
- 第一种情况是,如果要删除的节点没有子节点,只需要直接将父节点中,指向要删除节点的指针置为 null。比如图中的删除节点 55。
- 第二种情况是,如果要删除的节点只有一个子节点(只有左子节点或者右子节点),只需要更新父节点中,指向要删除节点的指针,让它指向要删除节点的子节点就可以了。比如图中的删除节点 13。
- 第三种情况是,如果要删除的节点有两个子节点,需要找到这个节点的右子树中的最小节点,把它替换到要删除的节点上。然后再删除掉这个最小节点,因为最小节点肯定没有左子节点(如果有左子结点,那就不是最小节点了),所以,我们可以应用上面两条规则来删除这个最小节点。比如图中的删除节点 18。
那首先要注意这个题目的函数返回值以及参数:
- 需要返回节点
- 参数为指向节点的指针,而不是指向节点的指针的引用,所以要处理好递归调用的时候的返回值。和这儿不用:二叉搜索树的C++实现,题目的情况是值传递,注意区分就好。
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(!root) return NULL;
if(root->val > key)
root->left = deleteNode(root->left, key);
else if(root->val < key)
root->right = deleteNode(root->right, key);
// 找到了该节点
// 1.该节点同时有左右子树
else if(root->left != NULL && root->right != NULL){
auto tmp = root->right;
while(tmp->left != NULL) tmp = tmp->left;
root->val = tmp->val;
root->right = deleteNode(root->right ,root->val);
}
// 2.该节点有左子树或者右子树
// 3.该节点为叶节点
else{
auto tmp = root;
if(tmp->left != NULL)//只有左子树
root = root->left;
else //只有右子树
root = root->right;
delete tmp;
tmp = nullptr;
}
return root;
}
};