leetcode450. 删除二叉搜索树中的节点

1.题目描述:

给定一个二叉搜索树的根节点root和一个值key,删除二叉搜索树中的key对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。一般来说,删除节点可分为两个步骤:首先找到需要删除的节点;如果找到了,删除它。

2.自己写的裹脚布代码:

思路和插入操作leetcode701. 二叉搜索树中的插入操作差不多,二叉搜索树的删除节点较为复杂分三种情况:①删除叶子节点:直接删除。②删除只有一颗子树的节点:子承父业。③删除有两颗子树的节点:记录删除节点右子树的最小值,递归删除最小值节点,将原来待删除节点的值置为最小值。细节就直接看代码注释了:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) return root;
        TreeNode keyNode = getKeynode(root, key);
        TreeNode parent = getParent(root, key);
        if (keyNode == null) return root;//删除根节点单独写
        if (keyNode == root) {
            if (keyNode.left == null && keyNode.right == null) return null;
            else if (keyNode.left == null) return keyNode.right;
            else if (keyNode.right == null) return keyNode.left;
            else {
                TreeNode minNode = getMinnode(keyNode.right);
                deleteNode(root, minNode.val);
                keyNode.val = minNode.val;
            }                
        } else {
            if (keyNode.left == null && keyNode.right == null) {//删除叶子节点
                if (parent.left == keyNode) parent.left = null;
                else parent.right = null;
            } else if (keyNode.left == null) {//删除单子树节点
                if (parent.left == keyNode) parent.left = keyNode.right;
                else parent.right = keyNode.right;
            } else if (keyNode.right == null) {
                if (parent.left == keyNode) parent.left = keyNode.left;
                else parent.right = keyNode.left;
            } else {//删除双子树节点
                TreeNode minNode = getMinnode(keyNode.right);
                deleteNode(root, minNode.val);
                keyNode.val = minNode.val;
            }
        }
        return root;
    }
    //找到待删除的节点
    public TreeNode getKeynode(TreeNode root, int key) {
        TreeNode temp = root;
        while (temp != null) {
            if (temp.val > key) temp = temp.left;
            else if (temp.val < key) temp = temp.right;
            else return temp;
        }
        return null;
    }
    //找到待删除结点的父节点,若待删除为root节点则返回null
    public TreeNode getParent(TreeNode root, int key) {
        TreeNode temp = root;
        TreeNode parent = null;
        while (temp != null) {
            if (temp.val > key) {
                parent = temp;
                temp = temp.left;
            }
            else if (temp.val < key) {
                parent = temp;
                temp = temp.right;
            }
            else return parent;
        }
        return null;
    }
    //找到最小值节点
    public TreeNode getMinnode(TreeNode root) {
        TreeNode temp = root;
        while (temp.left != null) temp = temp.left;
        return temp;
    }
}

3.递归:

依然利用递归函数的返回值来完成把节点从二叉树中移除的操作,绝。

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        root = delete(root, key);
        return root;
    }

    private TreeNode delete(TreeNode root, int key) {
        if (root == null) return null;
        if (root.val > key) {
            root.left = delete(root.left, key);
        } else if (root.val < key) {
            root.right = delete(root.right, key);
        } else {
            if (root.left == null) return root.right;
            if (root.right == null) return root.left;
            TreeNode temp = root.right;
            while (temp.left != null) temp = temp.left;
            root.val = temp.val;
            root.right = delete(root.right, temp.val);
        }
        return root;
    }
}

二刷:

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.val>key(后无return语句)还会进入else语句中
        else {
            if (root.left == null) return root.right;
            if (root.right == null) return root.left;
            TreeNode temp = root.right;
            while (temp.left != null) {
                temp = temp.left;
            }
            //改变树的高度:直接将root左子树拼接到右子树的最小节点左子树
            temp.left = root.left;
            root = root.right;//删除了root节点,将其右子树代替返回
            //不改变树的高度:
            //root.val = temp.val;//节点值被右子树最小节点替换,变相删除
            //root.right = deleteNode(root.right, root.val);//递归拼接删除最小节点的右子树
        }
        return root;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值