今天是二叉树相关算法学习的第七天。主要的学习内容有:二叉搜索树的最近祖先,以及二叉搜索树的插入和删除操作。
235. 二叉搜索树的最近公共祖先
题目链接:235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)
我刚拿到这个题,就直接用一般二叉树查找公共祖先的方法解决了问题。具体代码实现如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==NULL) return NULL;
if(root==p||root==q) return root;
TreeNode* left=lowestCommonAncestor(root->left,p,q);
TreeNode* right=lowestCommonAncestor(root->right,p,q);
if(left==NULL&&right!=NULL) return right;
else if(left!=NULL&&right==NULL) return left;
else if(left==NULL&&right==NULL) return NULL;
else return root;
}
};
当具备二叉搜索树这一性质后,可以更简单的查找两节点的公共祖先。因为二叉搜索树是具备有序性的,所以在遍历过程中,第一次出现节点的值在p节点和q节点值的中间时,该节点就是p节点和q节点的公共节点。按照前序遍历就可以。具体代码实现如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* result=new TreeNode();
bool isfirst=0;
void order(TreeNode* root,TreeNode* p,TreeNode* q)
{
if(root==NULL) return;
int max=-10010,min=-10010;
if(p->val>=q->val) max=p->val,min=q->val;
else max=q->val,min=p->val;
if(root->val>=min&&root->val<=max)
{
if(isfirst==0)
{
isfirst=1;
result=root;
}
}
lowestCommonAncestor(root->left,p,q);
lowestCommonAncestor(root->right,p,q);
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
order(root,p,q);
return result;
}
};
701.二叉搜索树中的插入操作
题目链接:701. 二叉搜索树中的插入操作 - 力扣(LeetCode)
这个题感觉比较简单,按照二叉搜索树的性质进行插入就可以。对于终止条件,如果插入的值大于根节点就往右走,小于根节点就往左走,遇到空值就进行插入即可。具体代码实现如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void order(TreeNode* root,int val)
{
if(root==NULL) return;
if(val>root->val&&root->right==NULL)
{
TreeNode* node=new TreeNode(val);
root->right=node;
}
if(val<root->val&&root->left==NULL)
{
TreeNode* node=new TreeNode(val);
root->left=node;
}
if(val>root->val)order(root->right,val);
else order(root->left,val);
}
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root==NULL)
{
TreeNode* node=new TreeNode(val);
return node;
}
order(root,val);
return root;
}
};
450.删除二叉搜索树中的节点
题目链接:450. 删除二叉搜索树中的节点 - 力扣(LeetCode)
这个题就比较复杂了,是看了题解做出来的,尤其是第五种情况的处理确实有点复杂。当要删除二叉搜索树里的某个节点时,涉及到五种情况:
1.删除节点本身为NULL,返回NULL
2.删除节点的左右节点都为空,直接返回NULL
3.删除节点的左节点为空,右节点不为空,返回该节点的右子树
4.删除节点的右节点为空,左节点不为空,返回该节点的左子树
5.删除节点的左右节点都不为空,首先查找该节点右子树的最左侧的值,将删除节点的左子树插入到删除节点右子树的最左节点的左子树。因为删除节点右子树的最左节点是大于删除节点左子树的最小值。然后返回删除节点的右子树。
具体代码实现如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
* right(right) {}
* };
*/
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) {
delete root;
return NULL;
}
if (root->left != NULL && root->right == NULL) {
TreeNode* node = root->left;
delete root;
return node;
}
if (root->left == NULL && root->right != NULL) {
TreeNode* node = root->right;
delete root;
return node;
}
if (root->left != NULL && root->right != NULL) {
TreeNode* cur = root->right;
while (cur->left != NULL)
cur = cur->left;
cur->left = root->left;
TreeNode* temp = root->right;
delete root;
return temp;
}
}
if (key < root->val)
root->left = deleteNode(root->left, key);
if (key > root->val)
root->right = deleteNode(root->right, key);
return root;
}
};