- 删除二叉搜索树中的节点
核心思路:删除操作需要根据节点的不同情况分别处理。如果删除的是叶子节点,直接删除即可;如果删除的节点只有一个子树,用该子树替换被删除的节点;如果删除的节点有两个子树,则需要找到左子树的最大值或右子树的最小值来替代被删除的节点。
代码逻辑:
deleteNode 方法:首先判断根节点是否为目标节点,如果是则直接调用 deleteRoot 方法处理;否则通过 findParent 方法找到目标节点的父节点,再根据目标节点在父节点的左右位置,调用 deleteRoot 方法删除目标节点。
deleteRoot 方法:处理删除根节点的逻辑。根据根节点的左右子树情况,分别返回相应的子树或调整子树结构。
findMax 方法:用于找到左子树的最大值。
findParent 方法:通过递归找到目标节点的父节点。
//450. 删除二叉搜索树中的节点
public TreeNode deleteNode(TreeNode root, int key) {
if (root != null && root.val == key) {
return deleteRoot(root);
}
TreeNode parent = findParent(root, key);
if (parent != null && parent.val > key) {
parent.left = deleteRoot(parent.left);
} else if (parent != null && parent.val < key) {
parent.right = deleteRoot(parent.right);
}
return root;
}
private TreeNode deleteRoot(TreeNode root) {if (root == null) {return null; // 如果根节点为空,直接返回 null}// 如果根节点没有左子树,直接返回右子树if (root.left == null) {return root.right;}// 如果根节点没有右子树,直接返回左子树if (root.right == null) {return root.left;}int max = findMax(root.left);// 将左子树的最大值节点的值赋给根节点root.val = max;// 删除左子树中的最大值节点root.left = deleteNode(root.left, max);return root;
}private int findMax(TreeNode root) {if (root == null) return 0;while (root.right != null) {root = root.right;}return root.val;
}private TreeNode findParent(TreeNode root, int key) {if (root == null) return null;if (root.left == null && root.right == null) return null;if ((root.left != null && root.left.val == key) || (root.right != null && root.right.val == key)) return root;if (root.val > key && root.left != null) {return findParent(root.left, key);} else if (root.val < key && root.right != null) {return findParent(root.right, key);}return null;
}
- 二叉搜索树中的插入操作
核心思路:根据二叉搜索树的性质,新插入的节点总是插入到某个叶子节点的位置。
代码逻辑:
insertIntoBST 方法:如果根节点为空,则直接创建一个新节点作为根节点;否则调用 insert 方法进行插入操作。
insert 方法:通过递归找到合适的插入位置,然后创建新节点并插入。
//701. 二叉搜索树中的插入操作
public TreeNode insertIntoBST(TreeNode root, int val) {
if (root == null) {
return new TreeNode(val);
}
insert(root, val);
return root;
}
private void insert(TreeNode root, int val) {if (root.val == val) {return;} else if (root.val > val) {if (root.left == null) {root.left = new TreeNode(val);} else {insert(root.left, val);}} else {if (root.right == null) {root.right = new TreeNode(val);} else {insert(root.right, val);}}
}
- 二叉搜索树的最近公共祖先
核心思路:利用二叉搜索树的性质,通过比较节点值的大小来确定最近公共祖先的位置。
代码逻辑:
lowestCommonAncestor1 方法:递归判断当前节点与目标节点的大小关系。如果当前节点的值在两个目标节点值之间,则当前节点就是最近公共祖先;如果两个目标节点的值都大于当前节点,则递归到右子树;反之则递归到左子树。
//235. 二叉搜索树的最近公共祖先
public TreeNode lowestCommonAncestor1(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) return null;
if (root.val == p.val || root.val == q.val) {
return root;
}
if ((root.val > p.val && root.val < q.val) || (root.val < p.val && root.val > q.val)) {
return root;
} else if ((root.val < p.val)) {
return lowestCommonAncestor1(root.right, p, q);
} else {
return lowestCommonAncestor1(root.left, p, q);
}
}