代码随想录day22
文章目录
- 一、二叉搜索树中的搜索
- 二、二叉搜索树的最近公共祖先
- 三、二叉搜索树的插入操作
- 四、删除二叉搜索树中的节点
一、二叉搜索树的搜索
先介绍一下二叉搜索树,二叉搜索树是有规律的,
二叉搜索树是一个有序树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树
所以二叉搜索树遍历起来还是比较方便的。
做题思路:做题之前想清楚递归的三个条件;1:确定递归函数的参数和返回值 2:确定终止条件 3:确定单层递归的的逻辑 下面三题都使用该步骤
跟普通二叉树的遍历是差不多的,这题也采用递归的方法,假如root.val>val,就说明目标值在左边,所以就执行root.left的操作;root.val<val,就明目标值在root的右边,就执行root.right的操作。
代码如下:
class Solution {
// 递归,利用二叉搜索树特点,优化
public TreeNode searchBST(TreeNode root, int val) {
if (root == null || root.val == val) {
return root;
}
if (val < root.val) {
return searchBST(root.left, val);
} else {
return searchBST(root.right, val);
}
}
}
二、二叉搜索树的最近公共祖先
做题思路:这篇全是用递归的方法解决,当root.val同时大于p和q和时候就执行root.left,当root.val同时小于p和q的时候,就执行root.right的操作,最终就能找到p和q的最近祖先。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root.val>p.val&&root.val>q.val){
return lowestCommonAncestor(root.left,p,q);
}
if(root.val<p.val&&root.val<q.val){
return lowestCommonAncestor(root.right,p,q);
}
return root;
}
}
三、二叉搜索树中的插入操作
做题思路:因为二叉搜索树是有规律的,所以插入的节点肯定落在尾部节点,这样就不会改变二叉搜索树的结构,会比较好做一点,(第三个图可以忽略,不用考虑那种写法)。本题依旧采用递归的方法,还是跟上两题的做法差不多,当root.val>val的时候,执行root.left的操作,就一直往左边搜索,右边跟这相反,我就不写了。等到最后的位置的时候,也就是root==null的时候,就在该位置插入目标节点。还有需要注意的几点我写在代码注释上,方便查看;
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root==null){
TreeNode node=new TreeNode(val);
return node;//将node返回到上一个root.left(或者right),
//然后就让上一个root指向了node
}
if(root.val>val){
root.left=insertIntoBST(root.left,val);
}
if(root.val<val){
root.right=insertIntoBST(root.right,val);
}
return root;
}
}
四、删除二叉搜索树中的节点
做题思路:该题也是采用递归的方法,但是有好几种情况,豆得考虑清楚先,
1.不存在目标节点
2.当左孩子和右孩子都为空
3.当左孩子为空右孩子不为空
4.当左孩子不为空,右孩子为空
5.左孩子和右孩子都不为空的情况(这是最复杂的情况,得改变二叉搜索树得结构) 详细步骤,
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&&root.right==null) return root.left;
else if(root.left==null&&root.right!=null) return root.right;
else if(root.left!=null&&root.right!=null){
TreeNode cur=root.right;
while(cur.left!=null){
cur=cur.left;
}
cur.left=root.left;
root=root.right;
return root;
}
}
if(root.val>key) root.left= deleteNode(root.left,key);
if(root.val<key) root.right= deleteNode(root.right,key);
return root;
}
}