二叉搜索树求最近公共祖先

题目理解

二叉搜索树是有序的,如果是左中右排的话,只要在有序数组中查找两数之间的根节点就可以了。不需要遍历整棵树,找到就可以。(?存疑)写法其实是遍历了整棵树的。

代码块

class Solution {
public:
    TreeNode* traversal(TreeNode* curr, TreeNode* p, TreeNode* q) {
        if (curr == NULL)
            return curr;
        if (curr->val > p->val && curr->val > q->val) {
            TreeNode* left = traversal(curr->left, p, q);
            if (left != NULL)
                return left;}
            if (curr->val < p->val && curr->val < q->val) {
                TreeNode* right = traversal(curr->right, p, q);
                if (right != NULL)
                    return right;
            }return curr;  
        }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == NULL)
            return root;
        return traversal(root, p, q);
    }
};

二叉搜索树中的插入操作

题目理解

在已知的一个二叉搜索树中插入一个节点,使插入操作之后该树依然是二叉搜索树。

思路

插入操作确实不会改变二叉树的结构,只需要根据二叉搜索树的性质即左子树小于根节点小于右子树新建一个节点即可。

代码

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;
    }
};

二叉搜索树中的删除操作

思路

对删除元素进行分情况讨论
叶子节点
左空节点
右空节点
左右都不空节点
自己就是空节点

代码

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
      if(root==NULL)  return root;
      if(root->val==key){
        if(root->left==NULL&&root->right==NULL) return NULL;
        if(root->left!=NULL&&root->right==NULL) return root->left;
        if(root->left==NULL&&root->right!=NULL) return root->right;
        else{
        TreeNode* curr=root->right;
        while(curr->left!=NULL)  {curr=curr->left;}
        curr->left = root->left;
        TreeNode*tmp=root;
        root =root->right;
        tmp->left=curr->left;
        delete tmp;
        return root;
        }
      }
      if(root->val>key) root->left=deleteNode(root->left,key);
      if(root->val<key) root->right=deleteNode(root->right,key);
      return root;
    }
};

本题总结

删除左右子树均不空节点的处理逻辑:
1.找到不小于它的右子树的最小值;
2.把它续在后面;
3.右子树取根节点代之。

小结

对搜索二叉树删除和插入节点都是相似的处理逻辑,即先进行根节点的处理逻辑,然后对左子树和右子树进行遍历操作。
找两个节点的公共祖先则是先定义left和right,然后对left和right 做条件判断。
可是为什么是这样的处理逻辑?

posted on 2025-11-24 19:22  FAfa_C++  阅读(20)  评论(0)    收藏  举报