LeetCode 235. 二叉搜索树的最近公共祖先
题目链接:LeetCode 235. 二叉搜索树的最近公共祖先
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL)
return root;
if(root->val > p->val && root->val > q->val)
{
TreeNode* left = lowestCommonAncestor(root->left,p,q);
if(left != NULL)
return left;
}//左子树中寻找
else if(root->val < p->val && root->val < q->val)
{
TreeNode* right = lowestCommonAncestor(root->right,p,q);
if(right != NULL)
return right;
}//右子树中寻找
return root;
}
};
思路: 利用二叉搜索树的特性(节点值一定大于左子树的值同时小于右子树的值),当节点值大于两个目标节点的值时在左子树中进行寻找,并返回寻找到的节点;当节点值小于两个目标节点的值时在右子树中进行寻找,并返回寻找到的节点。最后返回寻找到的根节点即可。
小结:当节点值在目标节点值之间时,则该节点一定是目标节点的最近公共祖先。
LeetCode 701.二叉搜索树中的插入操作
题目链接:LeetCode 701. 二叉搜索树中的插入操作
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root == NULL)//root为空寻找到叶子节点位置
{
TreeNode* node = new TreeNode(val);
return node;//设定新节点并将其返回
}
if(val > root->val)//插入值大于节点值时在右子树插入
root->right = insertIntoBST(root->right,val);//将节点的右子树设定为新节点
if(val < root->val)//插入值大于节点值时在左子树插入
root->left = insertIntoBST(root->left,val);//将节点的左子树设定为新节点
return root;//返回根节点
}
};
思路: 我们规定,在二叉树的叶子节点插入新节点(这样不会改变树的结构)。遍历终止条件即为:寻找到空节点,之后我们设定一个新节点,并将其返回。单层逻辑为对插入值与节点值进行比较,之后寻找到对应的叶子节点;此时我们将新节点返回给叶子节点的左右子树,完成插入操作。最后返回根节点即可。
小结:在进行遍历时,我们并没有改变root这个根节点,而是通过根节点的左右子树进行遍历,故返回时直接但返回root即可。
LeetCode 450.删除二叉搜索树中的节点
题目链接:LeetCode 450. 删除二叉搜索树中的节点
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
//确定终止条件以及返回值
if(root == NULL)
return NULL;//没有找到要删除的节点,返回空
if(key == root->val)//找到要删除的节点
{
if(root->right == NULL && root->left == NULL)//情况一,节点左右子树均为空(叶子节点)
{
delete root;
return NULL;//直接删除节点,返回空
}
else if(root->right != NULL && root->left == NULL)//情况二,节点右子树不为空,左子树为空
{
TreeNode* node = root->right;//保存右子树
delete root;//删除节点
return node;//返回右子树
}
else if(root->left != NULL && root->right == NULL)//情况三,节点左子树不为空,右子树为空
{
TreeNode* node = root->left;//保存左子树
delete root;//删除节点
return node;//返回左子树
}
else//情况四,节点左右子树均不为空
{
TreeNode* cur = root->right;//设定新节点为右子树
while(cur->left != NULL)//找到右子树最左叶子节点
{
cur = cur->left;
}
cur->left = root->left;//将最左叶子节点的左子树设定为原节点的左子树
TreeNode* node = root->right;//保存右子树
delete root;//删除节点
return node;//返回右子树
}
}
if(key > root->val)
root->right = deleteNode(root->right,key);
else if(key < root->val)
root->left = deleteNode(root->left,key);
return root;
}
};
思路:在删除节点时,我们需要将新的子节点给目标节点的父节点,故遍历返回值为新节点。在寻找节点时会出先两种大情况:寻找到需要删除的节点,没有寻找到需要删除的节点。没有寻找到要删除的节点时新节点为空,直接返回即可。而寻找到要删除的节点时,共有四种情况,对每一种情况进行对应操作并返回新节点即可。
小结: 找到目标节点的情况四中,也可以先将右子树移至左子树的叶子节点,之后将左子树返回。