文章目录
- 1 删除二叉树的节点
- 思路
- 其他代码
- 参考
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#算法公开课