题目
思路
- 先递归找节点,
- 如果找到节点值=要删除的节点值,进行删除操作,分四种情况
- 如果没找到对应的节点值,返回null
- 分四种情况删除
- 【A】情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
- 【B】情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
- 【C】情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
- 【D】情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左节点;或者把将删除节点的右子树头节点放到要删除节点的左子树的最右节点。(根据二叉搜索树的性质得来)
代码
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return root;
}
//没找到
if (root != null && root.val != key) {
root.left = deleteNode(root.left, key);
root.right = deleteNode(root.right, key);
return root;
}
//找到了!删除当前节点
if (root.val == key) {
if (root.left == null && root.right == null) {//左右都空,情况【A】
return null;
} else if (root.left != null && root.right == null) {//右空左不空,情况【C】
return root.left;
} else if (root.left == null && root.right != null) {//左空右不空,情况【B】
return root.right;
} else if (root.left != null && root.right != null) {//左右都不空,情况【D】
TreeNode cur = root.left;
while (cur.right != null) {
cur = cur.right;
}
cur.right = root.right;
return root.left;
// 或者
// TreeNode node = root.right;
// while (node.left != null) {
// node = node.left;
// }
// node.left = root.left;
// return root.right;
}
}
return null;
}
}
之前做的
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {//终止条件
return root;
}
if (root.val > key) {//向左搜素
root.left = deleteNode(root.left, key);
} else if (root.val < key) {//向右搜索
root.right = deleteNode(root.right, key);
} else {//找到了!删除当前节点
if (root.left == null && root.right == null) {//左右都空,情况【A】
return null;
} else if (root.left == null) {//左空右不空,情况【B】
return root.right;//直接把当前节点替换为右节点
} else if (root.right == null) {//右空左不空,情况【C】
return root.left;//直接把当前节点替换为左节点
} else {//左右都不空,情况【D】
TreeNode node = root.right;
while (node.left != null) {
node = node.left;
}
node.left = root.left;
return root.right;
//或者:
// TreeNode node = root.left;
// while (node.right != null) {
// node = node.right;
// }
// node.right = root.right;
// return root.left;
}
}
return root;
}
}