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

问题描述

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

首先找到需要删除的节点;
如果找到了,删除它。

提示:

节点数的范围 [0, 104].
-105 <= Node.val <= 105
节点值唯一
root 是合法的二叉搜索树
-105 <= key <= 105

解题思路

对于二叉搜索树,只用保证左子树小于根节点,右子树大于根节点。
对于删除有三种情况:

  1. 当删除的节点没有右子树时,使用左子树的根节点作为新的根节点。
  2. 当删除的节点没有左子树时,使用右子树的根节点作业新的根节点。
  3. 当同时有左子树和右子树时,将左子树放到右子树的最左节点上。

    二叉搜索树使用中序遍历方式时,得到的序列是一个有序的升序数列。二叉搜索树的特点是左子树都小于根节点,左子树的根节点必定是左子树中值最大的节点且小于根节点的值,在右子树中,也根据二叉搜索树的特点,可以得出,右子树的最左节点一定是在二叉树中的值中比根节点的值大于且差值最小。三者的关系是: 左子树根节点 < 要删除的节点 < 右子树的最左节点,当删除了节点之后,左子树的根节点与右子树的最左节点在序列是相邻的,所以将左子树的根节点作为右子树最在节点的左子树。最后因为删除的的左子树追加到它的右子树中,所以只能用右子树的根节点代替原来的节点。

代码实现

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) return null;
        if (root.val == key) {
			  if (root.right == null) {
				return root.left;
			} else if (root.left == null){
				return root.right;
			} else {
				TreeNode node = root.right;
				while (node.left != null) node= node.left;
				node.left = root.left;
				root = root.right;
				return root;
			}
        }
        if (root.val > key) {
            root.left = deleteNode(root.left,key);
        }else {
            root.right = deleteNode(root.right,key);
        }
        return root;
    }
}

实现细节

在遍历树时,我们会将返回的值重新赋值其左指针或右指针的值,一是为了保存每个节点的处理逻辑一致,二是为当删除了节点之后,会返回新的根节点,那么新的根节点作为代替原来的根节点返回,设置为要删除结点父结点的left或right属性的值。

总结

posted @ 2022-12-13 09:06  wzpro  阅读(20)  评论(0)    收藏  举报