235.二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点
235.二叉搜索树的最近公共祖先
这道题与二叉树的最近公共祖先很相似,二叉搜索树是二叉树的特殊情况,所以可以用上一题的过程来做这一道题。
但是这样子的话就没有用到二叉搜索树的性质,算法可以不太高校。
二叉搜索树的性质就是左<中<右。
因此,根据上一题,我们可以得到,如果根节点大于两个节点的最大值,就返回遍历左孩子的结果,如果根节点小于两个节点的最小值,就返回返回遍历右孩子的结果。
不然的话,就返回根节点的结果。
代码
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root->val>q->val&&root->val>p->val)
return lowestCommonAncestor(root->left,p,q);
else if(root->val<p->val&&root->val<q->val)
return lowestCommonAncestor(root->right,p,q);
return root;
}
};
701.二叉搜索树中的插入操作
如果根节点是空的,那我们自己造一个节点容纳这个元素,返回这个节点就好了。
如果根节点不为空,并且,根节点的大于目标值val,我们就让根节点的左孩子指针接收将要构造的左子树。
反之,用根节点的右孩子指针接收右子树。
代码
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root==nullptr)
{
TreeNode * p=new TreeNode(val);
return p;
}
if(root->val>val) root->left = insertIntoBST(root->left,val);
else if(root->val<val) root->right = insertIntoBST(root->right,val);
return root;
}
};
450.删除二叉搜索树中的节点
对于二叉搜索树,如果我们想要删除一个节点,我必须有父节点的指针,能够获取这个节点的位置,而只有前序遍历可以做到这样的事,因此,我们进行其前序遍历。
如果查找到的节点为空,我们直接返回nullptr。
如果查找到的节点值等于key,我们进行分类讨论,
①如果节点的左右孩子都是空,我们直接清除这块内存,并返回空即可。
②如果左右孩子有一个是空,我们返回这个孩子,并清除内存。
③如果左右孩子都不是空,我们让右子树的最左端孩子接受左子树,返回右子树,清除内存。
如果查到的节点值小于key,我们让节点的右孩子进行递归,
如果查到的节点值大于key,我们让节点的左孩子进行递归。
代码
class Solution {
public:
TreeNode* now;
TreeNode* deleteNode(TreeNode* root, int key) {
if(root==nullptr) return nullptr;
if(root->val==key)
{
if (root->left==nullptr&&root->right == nullptr)
{
delete root;
return nullptr;
}
else if(root->left&&root->right == nullptr)
{
TreeNode * p =root->left;
delete root;
return p;
}
else if(root->left==nullptr&&root->right)
{
TreeNode * p = root->right;
delete root;
return p;
}
else
{
TreeNode * p =root->right;
while(p->left!=nullptr)
p =p->left;
p->left = root->left;
p = root->right;
delete root;
return p;
}
}
if(root->val >key) root->left = deleteNode(root->left,key);
if(root->val<key) root->right = deleteNode(root->right,key);
return root;
}
};