二叉搜索树的最近公共祖先、二叉树的所有路径、删除二叉搜索树中的节点
二叉搜索树的最近公共祖先
1.递归的方法
利用二叉搜索树的性质,只要从上到下去遍历,遇到 cur节点是数值在[p, q]区间中则一定可以说明该节点cur就是q 和 p的公共祖先。 且一定是最近公共祖先。
递归的图解步骤
关键点:
- 如果 cur->val 大于 p->val,同时 cur->val 大于q->val,那么就应该向左遍历
- 需要注意的是此时不知道p和q谁大,所以两个都要判断
递归代码
// 递归法
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
return traversal(root, p, q);
}
public TreeNode traversal(TreeNode cur, TreeNode p, TreeNode q) {
if(cur==null) return null;
//中
//左
if(cur.val>p.val&&cur.val>q.val){
TreeNode left = traversal(cur.left, p, q);
if(left!=null) return left;
}
//右
if(cur.val<p.val&&cur.val<q.val){
TreeNode right = traversal(cur.right, p, q);
if(right!=null) return right;
}
return cur;
}
}
二叉搜索树中的插入操作
力扣连接:701. 二叉搜索树中的插入操作(中等)
1.递归的方法
由于是二叉搜索树,所以只要遍历二叉搜索树,找到空节点 插入元素就可以了,那么这道题其实就简单了。
递归的图解步骤
关键点:
- 有返回值的话,可以利用返回值完成新加入的节点与其父节点的赋值操作。
递归代码
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
return insert(root, val);
}
public TreeNode insert(TreeNode cur, int val) {
if(cur==null) return new TreeNode(val);
if(cur.val>val){
cur.left = insert(cur.left, val);
}
if(cur.val<val){
cur.right = insert(cur.right, val);
}
return cur;
}
}
删除二叉搜索树中的节点
力扣连接:450. 删除二叉搜索树中的节点(中等)
搜索树的节点删除要比节点增加复杂的多,有很多情况需要考虑
图解步骤
关键点:
有以下五种情况:
没找到删除的节点
- 第一种情况:遍历到空节点直接返回了
找到删除的节点
- 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
- 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
- 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
- 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
代码
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
return delete(root, key);
}
public TreeNode delete(TreeNode cur, int key) {
//1.没有找到删除的点
if(cur==null) return null;
//找到删除的点
if(cur.val==key){
//2.叶子节点,左右为空
if(cur.left==null&&cur.right==null){
return null;
}
//3.左不空,右空
else if(cur.left!=null&&cur.right==null){
return cur.left;
}
//4.左空,右不空
else if(cur.left==null&&cur.right!=null){
return cur.right;
}
//5.左不空,右不空 (cur.left!=null&&cur.right!=null)
else{
TreeNode findMaxLeft = cur.right;
while(findMaxLeft.left!=null) findMaxLeft = findMaxLeft.left;
findMaxLeft.left = cur.left;
return cur.right;
}
}
if(cur.val>key) cur.left = delete(cur.left,key);
if(cur.val<key) cur.right = delete(cur.right,key);
return cur;
}
}