【二叉树】LC405-删除二叉搜索树的节点

1 删除二叉树的节点

https://leetcode.cn/problems/delete-node-in-a-bst/description/

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

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

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

在这里插入图片描述

思路

删除一个树的某个节点,并返回一个树,此时需要采用有返回值的递归

public Node func(Node root) {
	
	if (root != null) {
		// 当前节点的处理
	    root.left = func(root.left);
	    root.right = func(root.eight);
	    return root;
	}
}

找到节点后可以删除,这里需要分很多种情况:

1 如果要删除的节点为叶子节点,此时直接删除就可以,对于Java来说,返回None即可
2 要删除的节点不是叶子节点,如果只有一个孩子,则返回其中的一个孩子,当前节点会被回收
3 要删除的节点不是叶子节点,两个孩子都存在,此时需要左孩子或者右孩子来填充当前的节点
如果使用左孩子填充,需要将要删除的节点的左孩子放到要删除右孩子的最左边(二叉搜索树的性质)
同样的,如果删除右孩子,需要将要删除节点的右孩子放到放到要删除节点左孩子的最右边(二叉搜索树的性质)

采用其一种方法即可,采用第一种,使用右孩子进行填充

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码:

class Solution{
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) return null;
        if (root.val == key) {
            if (root.left == null && root.right == null) return null;
            else if (root.left == null) return root.right;
            else if (root.right == null) return root.left;
            // 此时为左右孩子都不是null
            TreeNode node = root.right;
            while (node.left != null) {
                node = node.left;
            }
            node.left = root.left;
            return root.right;  // 返回当前节点的右孩子
        }
        root.left = deleteNode(root.left, key);
        root.right = deleteNode(root.right, key);
        return root;
    }
}

【注意】主要是删除当前节点左右孩子都有的情况,此时需要将当前删除节点的左孩子放到右孩子的最左边,此时使用一个循环解决

TreeNode node = root.right;
while (node.left != null) {
	node = node.left;
}
node.left = root.left;

其他代码

package binaryTree.LC450deleteBinaryTree;

import java.util.*;

class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    public TreeNode() {}
    public TreeNode(int val) {this.val = val;}

}

public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Solution solution = new Solution();
        while (in.hasNext()) {
            String[] strNums = in.nextLine().split(" ");
            int val = Integer.parseInt(in.nextLine());
            List<TreeNode> nodes = new LinkedList<>();
            for (String strNum: strNums) {
                if (!strNum.isEmpty()) {
                    if (strNum.equals("null")) nodes.add(null);
                    else nodes.add(new TreeNode(Integer.parseInt(strNum)));
                }
            }

            TreeNode root = constructTree(nodes);
            solution.deleteNode(root, val);

            preorderTree(root);

        }

    }

    public static void preorderTree(TreeNode root) {
        if (root != null) {
            System.out.print(root.val + " ");
            preorderTree(root.left);
            preorderTree(root.right);
        }
    }

    public static TreeNode constructTree(List<TreeNode> nodes) {
        if (!nodes.isEmpty()) {
            TreeNode node = nodes.remove(0);
            if (node != null) {
                node.left = constructTree(nodes);
                node.right = constructTree(nodes);
            }
            return node;
        }
        return null;
    }

}
/*
test case:
5 3 2 null null 4 null null 6 null 7
3
 */

参考

https://programmercarl.com/0450.删除二叉搜索树中的节点.html#算法公开课

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: L3-016题目描述了一个关于二叉搜索树结构的问题。根据引用和引用的定义,二叉搜索树是一种具有特定性质的二叉树。具体来说,对于一棵二叉搜索树,如果它的左子树不为空,则左子树上所有节点的值都小于根节点的值;如果它的右子树不为空,则右子树上所有节点的值都大于根节点的值;而且它的左子树和右子树也都是二叉搜索树。在L3-016题目中,给定了一系列互不相等的整数,按顺序将它们插入一棵初始为空的二叉搜索树。题目要求判断给定的描述是否正确,描述了树的结构。根据引用的描述,我们可以根据插入的顺序和节点之间的关系来判断描述是否正确。例如,如果描述中的节点关系和插入顺序一致,那么描述就是正确的。具体来说,“2是树的根”、“1和4是兄弟节点”、“3和0在同一层上”、“2是4的双亲节点”、“3是4的左孩子”等描述都是正确的。而“4是2的左孩子”、“1和3是兄弟节点”等描述是不正确的。因此,在判断描述是否正确时,我们需要根据二叉搜索树的性质和节点的插入顺序来进行分析。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [L3-1 二叉搜索树的结构](https://blog.csdn.net/qq_35104140/article/details/79719945)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [undefined](undefined)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [团体程序设计天梯赛-练习集 -- L3-016. 二叉搜索树的结构(模拟)](https://blog.csdn.net/aozil_yang/article/details/70477913)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值