【代码随想录】day22

文章介绍了二叉搜索树的三个关键操作:使用递归实现的235近似最近公共祖先查找,两种插入方法(笨办法和优化版),以及模拟递归的删除节点算法。着重展示了优化后的插入和删除操作,以简化代码并提高效率。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


提示:以下是本篇文章正文内容,下面案例可供参考

一、235二叉搜索树的最近公共祖先

class Solution {
public:
    //p小 q大
    TreeNode* traversal(TreeNode* node, TreeNode* p, TreeNode* q) {
        if (node == nullptr) return node;
        if (node->val > p->val && node->val > q->val) {
            return traversal(node->left, p, q);
        }
        else if (node->val < p->val && node->val < q->val ) {
            return traversal(node->right, p, q);
        }
        return node;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        return traversal(root, p, q);        
    }
};

二、701二叉搜索树中的插入操作

笨办法做的,感觉这题让我写的无比复杂

class Solution {
public:
    TreeNode* insertPos = nullptr;
    void traversal(TreeNode* cur, int val) {
        if (cur == nullptr) return;
        traversal(cur->left, val);
        if (insertPos == nullptr && cur->val >= val) {
            insertPos = cur;
            return;
        }
        traversal(cur->right, val);
    }
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        TreeNode* node = new TreeNode(val);
        if (root == nullptr) return node;
        traversal(root, val);
        if (insertPos == nullptr) {
            node->left = root;
            return node;            
        }
        TreeNode* temp = nullptr;
        if (val < insertPos->val) {
            temp = insertPos->left;
            insertPos->left = node;
        }
        else if (val > insertPos->val) {
            temp = insertPos->right;
            insertPos->right = node;
        }
        if (temp != nullptr) {
            if (temp->val > val) node->right = temp;
            else node->left = temp;
        }
        return root;
    }
};

二叉搜索树插入任何结点都可以在叶子结点找到插入位置,优化版:

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

三、450删除二叉搜索树中的节点

模拟法。。递归写的少,太难想了,感觉很抽象

class Solution {
public:
    TreeNode* pre = nullptr;
    TreeNode* deleteNode(TreeNode* root, int key) {
        TreeNode* cur = root;
        while (cur) {
            if (cur->val == key) break;
            pre = cur;
            if (cur->val > key) cur = cur->left;
            else cur = cur->right;
        }
        //如果删除的结点不在树里,直接返回root
        if (cur == nullptr) return root;
        if (cur == root) {
            if (cur->right == nullptr) return cur->left;
            TreeNode* temp = cur->left;
            root = cur->right;
            cur = cur->right;
            while (cur->left) {
                cur = cur->left;
            }
            cur->left = temp;
            return root;
        }
        //如果删除的结点为叶子结点,直接删掉就行
        if (cur->left == nullptr && cur->right == nullptr) {
            if (pre->val > cur->val) pre->left = nullptr;
            else pre->right = nullptr;
        }
        //如果删除的结点的右子树不为空
        if (cur->right) {
            TreeNode* temp = cur->left;
            if (pre->val > cur->val) {
                pre->left = cur->right;
                pre = pre->left;
            }
            else if (pre->val < cur->val) {
                pre->right = cur->right;
                pre = pre->right;
            }
            //temp插到右子树的最左叶子结点
            while (pre->left) {
                pre = pre->left;
            }
            pre->left = temp;
        }
        //如果删除的结点的右子树为空,左子树不为空
        if (cur->left) {
            if (pre->val > cur->val) {
                pre->left = cur->left;
            }
            else {
                pre->right = cur->left;
            }
        }
        return root;
    }
};

确实写的复杂了。在左右子树都不为空的那里多写了个条件判断,实际上是没有必要的,放左子树右子树都行。优化后的代码:

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) {
                auto retNode = root->right;
                delete root;
                return retNode;
            }
            //左不空右空
            else if (root->right == nullptr) {
                auto retNode = root->left;
                delete root;
                return retNode;
            }
            //左右都不空
            else {
                TreeNode* cur = root->right;
                while (cur->left) {
                    cur = cur->left;
                }
                cur->left = root->left;
                return root->right;
            }
        }
        if (root->val < key) {
            root->right = deleteNode(root->right, key);
        }
        else {
            root->left = deleteNode(root->left, key);
        }
        return root;

    }
};

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值