二叉搜索树的应用
235.二叉搜索树的最近公共祖先
- 递归法: 求最近公共祖先,一定是在分岔口, 那么对于二叉搜索树而言, 无需后序遍历, 只要找到一个节点的值大于p, 小于q, 则其一定是最近公共祖先, 然后将找到的节点不断return上去即可
代码:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return null;
if(root.val > Math.max(p.val, q.val)) {
// 分叉点一定在其左子树
return lowestCommonAncestor(root.left, p, q);
}else if(root.val < Math.min(p.val, q.val)) {
// 分叉点一定在其右子树
return lowestCommonAncestor(root.right, p, q);
}else {
// 当前节点是分叉点, 为目标节点, 需要返回
return root;
}
}
}
701.二叉搜索树中的插入操作
两步走:
- 首先找到插入点, 插入点一定可以是当前节点为null的节点
- 因为需要返回根节点, 所以需要寻找的过程中不断地构造搜索路径上的二叉树
代码:
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root == null) {
return new TreeNode(val);
}
if(val > root.val) {
root.right = insertIntoBST(root.right, val);
}else {
root.left = insertIntoBST(root.left, val);
}
return root;
}
}
450.删除二叉搜索树中的节点
分情况:
-
删除的节点为叶子节点 --- 直接删
-
删除的节点为单亲孩子 --- 用非空子节点代替它
-
删除的是有双孩子的节点 --- 用右孩子代替它(同时需要将左孩子挂到右孩子的左孩子最深处)
-
同理: 需要返回根节点, 所以需要不断的构造搜索路径上的二叉树 代码:
class Solution {
// 分情况:
// 1. 删除的节点为叶子节点 --- 直接删
// 2. 删除的节点为单亲孩子 --- 用非空子节点代替它
// 3. 删除的是有双孩子的节点 --- 用右孩子代替它
public TreeNode deleteNode(TreeNode root, int key) {
if(root == null) return null;
if(root.val > key){
root.left = deleteNode(root.left, key);
}else if(root.val < key) {
root.right = deleteNode(root.right, key);
}else {
// 找到目标节点
if(root.right == null) {
root = root.left;
}else{
TreeNode curr = root.right;
// 找到最左边的 null 节点
while(curr.left != null){
curr = curr.left;
}
curr.left = root.left;
root = root.right;
}
}
return root;
}
}