内容:
- 二叉搜索树的最近公共祖先(235)
- 二叉搜索树中的插入操作(701)
- 删除二叉搜索树中的节点(450)
1. 二叉搜索树的最近公共祖先
难度:🔥🔥🔥
建议:相对于二叉树的最近公共祖先本题就简单一些了,因为可以利用二叉搜索树的特性
1.1 思路分析
普通二叉树求最近公共祖先需要使用回溯,从底向上来查找。
二叉搜索树就不用了,因为搜索树有序(相当于自带方向),那么只要从上向下遍历就可以了。
并且此题只需要遍历一条边。如果当前节点的值大于p,q的值,则需要向左子树去递归搜索,反之向右子树递归搜索
1.2 代码实现
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//本题使用何种遍历都可以
if (root == null) {
return null;
}
//如果当前节点的值大于p,q的值,则需要向左子树去递归搜索
if (root.val > p.val && root.val > q.val) {
TreeNode left = lowestCommonAncestor(root.left,p,q);
if (left != null) {
return left;
}
}
if (root.val < p.val && root.val < q.val) {
TreeNode right = lowestCommonAncestor(root.right,p,q);
if (right != null) {
return right;
}
}
return root;
}
}
1.3 注意事项
1.4 收获总结
2. 二叉搜索树中的插入操作
难度:🔥🔥
建议:本题比想象中简单,可以先自己想一想应该怎么做,然后看视频讲解,就会发现本题为什么比较简单了
2.1 思路分析
只需要按照二叉搜索树的规则去遍历,遇到空节点就插入节点就可以了
如图:
2.2 代码实现
lass Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
//找到叶子节点插入即可,无需改变树的结构
if (root == null) {
TreeNode node = new TreeNode(val);
return node;
}
if (root.val > val) {
root.left = insertIntoBST(root.left,val);
}
if (root.val < val) {
root.right = insertIntoBST(root.right,val);
}
return root;
}
}
2.3 注意事项
2.4 收获总结
3. 删除二叉搜索树中的节点
难度:🔥🔥🔥🔥
建议:相对于插入操作,本题就有难度了,涉及到改树的结构
3.1 思路分析
删除节点有以下五种情况:
- 第一种情况:没找到删除的节点,遍历到空节点直接返回了
- 找到删除的节点
- 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
- 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
- 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
- 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
第五中情况如图:
3.2 代码实现
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
//终止条件
if (root == null) {
return null;
}
//如果找到了要删除的节点,分四种情况讨论
if (root.val == key) {
//1.叶子节点
if (root.left == null && root.right == null) {
return null;
//2.左不空右空
} else if (root.left != null && root.right == null) {
return root.left;
//3.左空右不空
} else if (root.left == null && root.right != null) {
return root.right;
//4.左右都不为空
}else {
TreeNode cur = root.right;
while (cur.left != null) {
cur = cur.left;
}//cur此时指向root右子树的左子树中最小的数
cur.left = root.left;
return root.right;
}
}
if (root.val > key) {
root.left = deleteNode(root.left,key);
}
if (root.val < key) {
root.right = deleteNode(root.right,key);
}
return root;
}
}
3.3 注意事项
3.4 收获总结
删除节点涉及到结构的调整所以相对二叉搜索树添加节点要难。
关键在于第五种情况,需要自己去深刻理解。初学掌握递归这种写法就够了。