递归新的理解:对于二叉树的各项遍历,中是处理的节点,左右是递归遍历,当前层中处理完之后的结果是返回给上一层递归的变量,上一层递归可以是左子树递归或者是右子树递归,这里只需要在左子树递归和右子树递归的后面写对应的后续方法即可,不用讨论该返回到左子树递归还是右子树递归。
这一题也可以用昨天的二叉树的方法来解决,但是这个是二叉搜索树,可以利用二叉搜索树的特性来进行解决。
递归法:这里只需要想明白一个点,就是节点第一次处于p和q的中间时就是最近的公共祖先。因为二叉搜索树中序遍历递增的特性,中间节点的值介于左右子树的值之间,假如p在根节点的左子树中,q在根节点的右子树中,如果节点向左或者向右遍历的话,就一定会错过其中一个了。
终止条件:当节点值介于p和q之间时,返回该节点
单层处理逻辑:当节点值大于q和p时,向左遍历,当节点值小于p和q时,向右遍历
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null){
return null;
}
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;
}
}
迭代法:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null){
return null;
}
while(root!=null){
if(root.val>p.val&&root.val>q.val){
root=root.left;
}else if(root.val<p.val&&root.val<q.val){
root=root.right;
}else{
return root;
}
}
return root;
}
}
这一题也只要理解,在二叉搜索树中,插入节点的操作都可以在叶子节点完成。就比较简单了,只要找满足符合条件的叶子节点即可
终止条件:遍历到叶子节点
单层处理逻辑:遍历到叶子节点,新建一个节点,将新节点返回到上一层递归,将该节点放在该层节点的左或者右子树。
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root==null){
TreeNode node=new TreeNode(val);
return node;
}
if(root.val>val){
TreeNode left=insertIntoBST(root.left,val);
root.left=left;
}
if(root.val<val){
TreeNode right=insertIntoBST(root.right,val);
root.right=right;
}
return root;
}
}
删除节点涉及到二叉树的结构调整。这里删除节点分为五种条件。
终止条件:遇到要删除的节点,根据不同情况,返回不同节点值
单层处理逻辑:也就是遇到要删除的节点,根据不同情况来进行删除和结构的调整
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
//1.要删除的节点为null
if(root==null){
return null;
}
if(root.val==key){
//2.要删除的节点左右子树为空,直接将该节点置空
if(root.left==null&&root.right==null){
return null;
}
//3.要删除的节点左子树不为空,右子树为空,直接将该节点父节点的左指针移到节点左子树
if(root.left!=null&&root.right==null){
return root.left;
}
//4.要删除的节点右子树不为空,左子树为空,直接将该节点父节点的右指针移到节点右子树
if(root.left==null&&root.right!=null){
return root.right;
}
//5.要删除的节点左右子树都不为空,要找到该节点右子树中最小的节点将其左子树移过去
if(root.left!=null&&root.right!=null){
TreeNode cur=root.right;
while(cur.left!=null){
cur=cur.left;
}
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;
}
}