一、二叉搜索树的公共祖先
二叉搜索树独特的性质可以让我在开始就可以通过比较根节点和目标pq节点值的大小来确定遍历方向。
这题依旧是用left来接受左子树返回上来的有效节点地址,无效(遍历到叶子后也没找到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* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==nullptr)return root;
if(root->val>p->val&&root->val>q->val){
TreeNode*left=lowestCommonAncestor(root->left,p,q);
if(left!=nullptr)return left;
}
if(root->val<p->val&&root->val<q->val){
TreeNode*right=lowestCommonAncestor(root->right,p,q);
if(right!=nullptr)return right;
}
return root;
}
};
二、 二叉搜索树的插入
我自己第一遍的写法是根据大小关系来遍历左右子树,然后遍历到叶子节点再插入。这样做会漏掉一个用例就是,root为空,此时返回还为空,不能进行插入操作。
/**
* 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* insertIntoBST(TreeNode* root, int val) {
if(root==nullptr)return root;
if(root->val>val){
TreeNode*left=insertIntoBST(root->left,val);
if(left==nullptr){
TreeNode*node=new TreeNode(val);
root->left=node;
return root;
}
}
if(root->val<val){
TreeNode*right=insertIntoBST(root->right,val);
if(right==nullptr){
TreeNode*node=new TreeNode(val);
root->right=node;
return root;
}
}
return root;
}
};
所以在此基础上,把插入节点的操作改成终止条件。直接进行root->left和right的赋值就行
/**
* 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* insertIntoBST(TreeNode* root, int val) {
if(root==nullptr){
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;
}
};
三、二叉搜索树删除节点
删除的节点有以下几种情况:
1.叶子节点,直接删
2.父节点,但只有一个儿子,把儿子继承给爷爷,直接删
3.父节点,俩儿子,左儿子是小儿子,右儿子是大儿子(二叉搜索树的性质)把小儿子交给大儿子 ,然后再把大儿子交给爷爷,然后删除
/**
* 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==nullptr)return root;
if(root->val==key){
if(root->left==nullptr&&root->right==nullptr){
delete root;
return nullptr;
}
else if(root->left==nullptr&&root->right!=nullptr){
TreeNode*temp=root->right;
delete root;
return temp;
}
else if(root->left!=nullptr&&root->right==nullptr){
TreeNode*temp=root->left;
delete root;
return temp;
}
// else if(root->left!=nullptr&&root->right!=nullptr){
else{
TreeNode*cur=root->right;
while(cur->left!=nullptr){
cur=cur->left;
}
cur->left=root->left;
root=root->right;
return root;
}
}
if(root->val>key)root->left=deleteNode(root->left,key);
if(root->val<key)root->right=deleteNode(root->right,key);
return root;
}
};