[leetCode]450. 删除二叉搜索树中的节点
递归
需要想清楚五种情况如注释所示,利用递归的返回值来删除目标节点
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
// 第一种情况,没有找到删除节点直接返回null
if (root == null) return root;
if (root.val == key) {
// 第二种情况,左右孩子都为空(叶子节点)直接返回null
// 第三种情况,左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
if (root.left == null) return root.right;
// 第四种情况,右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
else if (root.right == null) return root.left;
// 第五种情况,左右孩子都不为空,则将删除节点的左子树放到删除节点的右子树最左面节点的左孩子
// 并返回删除节点的右孩子为新的根节点
else {
TreeNode cur = root.right;
while (cur.left != null) { // 找到右子树最左面的节点
cur = cur.left;
}
cur.left = root.left; // 把要删除的节点的左子树放在cur的左孩子位置
root = root.right; // 返回root右孩子作为新root
return root;
}
}
if (root.val > key) root.left = deleteNode(root.left, key);
if (root.val < key) root.right = deleteNode(root.right, key);
return root;
}
}
使用删除二叉树节点的方法
代码中目标节点(要删除的节点)被操作了两次:
第一次是和目标节点的右子树最左面节点交换。
第二次直接被NULL覆盖了。
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) return root;
if (root.val == key) {
if (root.right == null) return root.left; // 这里是第二次操作目标值起到删除作用
TreeNode cur = root.right;
while (cur.left != null) {
cur = cur.left;
}
// 交换删除节点与删除节点右子树最左边节点的值
swap(cur, root);
}
root.left = deleteNode(root.left, key);
root.right = deleteNode(root.right, key);
return root;
}
private void swap(TreeNode p, TreeNode q) {
int tmp = p.val;
p.val = q.val;
q.val = tmp;
}
}
迭代
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) return root;
TreeNode cur = root;
TreeNode pre = null; // 记录父节点,用来删除cur
while (cur != null) {
if (cur.val == key) break;
pre = cur;
if (cur.val > key) cur = cur.left;
else cur = cur.right;
}
if (pre == null) { // 如果搜索树只有头节点
return deleteOneNode(cur);
}
// pre 要知道删除的是左孩子还是右孩子
if (pre.left != null && pre.left.val == key) {
pre.left = deleteOneNode(cur);
}
if (pre.right != null && pre.right.val == key) {
pre.right = deleteOneNode(cur);
}
return root;
}
// 将目标节点的左子树连接到目标节点的右子树最左边的节点上
// 返回目标节点的右孩子作为新的根节点
private TreeNode deleteOneNode(TreeNode target) {
if (target == null) return target;
if (target.right == null) return target.left;
TreeNode cur = target.right;
while (cur.left != null) {
cur = cur.left;
}
cur.left = target.left;
return target.right;
}
}