LeetCode 450删除二叉搜索树中的节点
-
题目简述:给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:首先找到需要删除的节点;如果找到了,删除它。
-
输入:root = [5,3,6,2,4,null,7] key = 3
输出:[5,4,6,2,null,null,7] 或者 [5,2,6,null,4,null,7]
-
思路:
如果
key > root->val
,说明要删除的节点在右子树,递归到右子树处理如果
key < root->val
,说明要删除的节点在左子树,递归到左子树处理如果
key = root->val
,则当前节点就是要删除的节点:按照目标点有无子树划分4种情况- 无子树即当前节点是叶子节点:直接删除
root==NULL
- 无左子树:把右子树接到父节点上,特判下根节点
- 无右子树:把左子树接到父节点上,特判下根节点
- 即有左子树又有右子树:左子树的最右叶子节点 和 右子树的最左叶子节点中任意一个swap到target节点后,删除掉目标目标节点
- 无子树即当前节点是叶子节点:直接删除
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(!root) return root;
if(key > root->val) // 如果key大于root->val, 递归到右子树处理
{
root->right = deleteNode(root->right, key);
return root;
}
if(key < root->val) // 如果key小于root->val, 递归到左子树删除
{
root->left = deleteNode(root->left, key);
return root;
}
if(!root->left) // 如果key = root->val,且左子为null,根变成右子根
{
TreeNode* tmp = root->right;
delete root;
return tmp;
}
if(!root->right) // 如果key = root->val, 且右子为null,根变成左子根
{
TreeNode* tmp = root->left;
delete root;
return tmp;
}
//当目标点左右都有子树时
TreeNode* tmp = root->right;
while (tmp->left) tmp = tmp->left; // 找到右子树中最左叶子节点,与root->val交换
swap(root->val, tmp->val);
root->right = deleteNode(root->right, key); // 再在交换过的树中删除key
return root;
#if 0
//等价写法
TreeNode* tmp = root->left;
while (tmp->right) tmp = tmp->right; // 找到左子树中最右叶子节点,与root->val交换
swap(root->val, tmp->val);
root->left = deleteNode(root->left, key); // 再在交换过的树中删除key
return root;
#endif
}
};