6.5 搜索树

This commit is contained in:
zhangsan 2025-06-05 11:00:40 +08:00
parent 566e4136f5
commit 0659fb690e
2 changed files with 101 additions and 0 deletions

View File

@ -0,0 +1,64 @@
package tree;
/**
* 题目450. 删除二叉搜索树中的节点 (deleteNode)
* 描述给定一个二叉搜索树的根节点 root 和一个值 key删除二叉搜索树中的 key 对应的节点并保证二叉搜索树的性质不变返回二叉搜索树有可能被更新的根节点的引用
* 一般来说删除节点可分为两个步骤
* 首先找到需要删除的节点
* 如果找到了删除它
*
* 示例 1
输入root = [5,3,6,2,4,null,7], key = 3
输出[5,4,6,2,null,null,7]
解释给定需要删除的节点值是 3所以我们首先找到 3 这个节点然后删除它
一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示
另一个正确答案是 [5,2,6,null,4,null,7]
* 链接https://leetcode.cn/problems/delete-node-in-a-bst/
*/
//不会
public class DeleteNode {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
// 没找到直接返回 null
return null;
}
if (key < root.val) {
// 待删除节点在左子树
root.left = deleteNode(root.left, key);
} else if (key > root.val) {
// 待删除节点在右子树
root.right = deleteNode(root.right, key);
} else {
// 找到要删除的节点 root
// 情况 1 & 2只有 0 个或 1 个子节点
if (root.left == null) {
// 用右子树替代当前节点右子树可能为 null 或者是一个节点
return root.right;
} else if (root.right == null) {
// 用左子树替代当前节点
return root.left;
}
// 情况 3左右子节点都存在
// 找到右子树的最小节点中序后继
TreeNode successor = findMin(root.right);
// 用后继节点的值覆盖当前节点
root.val = successor.val;
// 在右子树中删除这个后继节点它要么是叶子要么只有右子节点
root.right = deleteNode(root.right, successor.val);
}
// 返回删除结束后当前子树的根
return root;
}
// 辅助函数在以 node 为根的子树中找到最小节点一直往左即可
private TreeNode findMin(TreeNode node) {
while (node.left != null) {
node = node.left;
}
return node;
}
}

View File

@ -0,0 +1,37 @@
package tree;
/**
* 题目669. 修剪二叉搜索树 (trimBST)
* 描述给你二叉搜索树的根节点 root 同时给定最小边界low 和最大边界 high通过修剪二叉搜索树使得所有节点的值在[low, high]
* 修剪树 不应该 改变保留在树中的元素的相对结构 (如果没有被移除原有的父代子代关系都应当保留) 可以证明存在 唯一的答案
* 所以结果应当返回修剪好的二叉搜索树的新的根节点注意根节点可能会根据给定的边界发生改变
*
* 示例 1
输入root = [1,0,2], low = 1, high = 2
输出[1,null,2]
* 链接https://leetcode.cn/problems/trim-a-binary-search-tree/
*/
//不会
public class TrimBST {
public TreeNode trimBST(TreeNode root, int low, int high) {
if (root == null) {
return null;
}
// 情况一当前节点值过小左子树都小于它 => 整个左子树都可丢弃
if (root.val < low) {
return trimBST(root.right, low, high);
}
// 情况二当前节点值过大右子树都大于它 => 整个右子树都可丢弃
if (root.val > high) {
return trimBST(root.left, low, high);
}
// 情况三当前节点值在区间 [low, high] 需要保留
// 但左右子树仍需递归修剪
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
}
}