1.二叉搜索树的最近公共祖先
思路:(对比普通二叉树的最近公共祖先)
1.如果遍历到的结点大于p和q,那么p和q的公共祖先一定在该结点的左子树;
2.如果遍历到的结点小于p和q,那么p和q的公共祖先一定在该结点的右子树;
3.若该结点的值在p和q的中间,那么该结点一定是p和q的公共祖先,且为最近公共祖先。所以,可以从上往下进行遍历。
4.二叉搜索树是有序的,要利用好这一点。
5.二叉搜索树:中序遍历。(本题无中结点的处理逻辑)从上向下遍历。
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 return NULL;
}
else if (root -> val < p -> val && root -> val < q -> val){
TreeNode* right = lowestCommonAncestor(root -> right,p,q);
if(right != NULL) return right;
else return NULL;
}
else{
return root;
}
}
};
2.二叉搜索树的插入操作
https://leetcode.cn/problems/insert-into-a-binary-search-tree/
思路:
1.二叉搜索树中,一定要考虑清楚:新插入的结点放在对应的叶子结点即可。并不需要去改变树的结构。
2.只要遍历二叉搜索树,找到空节点 插入元素就可以了。
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root == NULL){
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;
}
};
3.删除二叉搜索树中的结点
思路:
1.删除结点的话,需要改变树的结构。相比于插入操作,要更复杂。因为二叉搜索树添加节点只需要在叶子上添加就可以的,不涉及到结构的调整,而删除节点操作涉及到结构的调整。
2.进行删除操作的话,需要考虑清楚五种情况:
(1)未找到需要删除的结点;
(2)找到了需要删除的结点,是叶子结点,左为空,右为空;
(3)左不为空,右为空;
(4)左为空,右不为空;
(5)左不为空,右不为空。
其中,第五种情况最为复杂,需要仔细考虑删除操作的方式。
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* retNode = root -> right;
delete root;
return retNode;
}
if(root -> left != NULL && root -> right == NULL){
TreeNode* retNode = root -> left;
delete root;
return retNode;
}
if(root -> left != NULL && root -> right != NULL){
TreeNode* cur = root -> right;
while(cur -> left != NULL){
cur = cur -> left;
}
cur -> left = root -> left;
TreeNode* retNode = root->right;
delete root;
return retNode;
}
}
if(root -> val > key) root -> left = deleteNode(root -> left,key);
if(root -> val < key) root -> right = deleteNode(root -> right,key);
return root;
}
};