LeetCode701. 二叉搜索树中的插入操作

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


一、题目

给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果

示例 1:

img

输入:root = [4,2,7,1,3], val = 5
输出:[4,2,7,1,3,5]
解释:另一个满足题目要求可以通过的树是:

示例 2:

输入:root = [40,20,60,10,30,50,70], val = 25
输出:[40,20,60,10,30,50,70,null,null,25]

示例 3:

输入:root = [4,2,7,1,3,null,null,null,null,null,null], val = 5
输出:[4,2,7,1,3,5]

提示:

  • 树中的节点数将在 [0, 104]的范围内。
  • -108 <= Node.val <= 108
  • 所有值 Node.val独一无二 的。
  • -108 <= val <= 108
  • 保证 val 在原始BST中不存在。
二、题解
方法一:递归(寻找合适的位置作为叶子结点插入)

算法思路

  1. 理解二叉搜索树性质: 首先,我们要理解什么是二叉搜索树(BST)以及它的性质。在BST中,每个节点的值都大于其左子树中的节点值,且小于其右子树中的节点值。

  2. 确定插入位置: 我们要做的是将一个新值插入到BST中。为了保持BST的性质,我们需要找到一个合适的位置来插入这个值。我们可以从根节点开始,比较新值与当前节点的值,根据大小关系来决定是往左子树还是右子树搜索。

  3. 递归插入: 一旦找到了合适的插入位置,我们可以创建一个新的节点,并将其插入到该位置。如果新值小于当前节点的值,则继续在左子树中递归寻找插入位置;如果新值大于当前节点的值,则在右子树中递归寻找插入位置。最后找到一个合适的位置作为叶子结点插入。

具体实现

class Solution {
public:
    // 递归函数,用于在BST中插入新节点
    void findWay(TreeNode *root, int val, TreeNode *newnode) {
        if (root->val > val) {
            if (root->left == nullptr) {
                root->left = newnode;
                return;
            } else {
                findWay(root->left, val, newnode); // 继续在左子树中寻找插入位置
            }
        } else {
            if (root->right == nullptr) {
                root->right = newnode;
                return;
            } else {
                findWay(root->right, val, newnode); // 继续在右子树中寻找插入位置
            }
        }
    }
    
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if (root == nullptr) {
            TreeNode *node = new TreeNode(val); // 创建新节点
            return node;
        }
        TreeNode *newnode = new TreeNode(val); // 创建新节点
        findWay(root, val, newnode); // 调用递归函数插入新节点
        return root;
    }
};

算法分析

  • 时间复杂度:在最坏情况下,我们需要遍历树的高度,所以插入的时间复杂度是 O(h),其中 h 是树的高度,对于一个平衡的BST来说,h 是 log(n) 级别。
  • 空间复杂度:由于递归调用会占用函数调用栈的空间,所以空间复杂度是 O(h),同样在平衡BST情况下,空间复杂度是 log(n) 级别。

还有一种带记录父节点的写法

class Solution {
public:
    TreeNode *parent;
    void findWay(TreeNode *cur, int val) {
        if(cur == nullptr){
            TreeNode *newnode = new TreeNode(val);
            if(parent->val > val){
                parent->left = newnode;
            }else{
                parent->right = newnode;
            }
            return;
        }
        parent = cur;
        if(cur->val > val){
            findWay(cur->left, val);
        }else{
            findWay(cur->right, val);
        } 
        return;
    }
    
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        parent = new TreeNode(0);
        if (root == nullptr) {
            root = new TreeNode(val);
        }else{
            findWay(root, val);
        }

        return root;
    }
};

返回节点的递归
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* insertIntoBST(TreeNode* root, int val) {
        if (root == nullptr) {
            return new TreeNode(val); // 可以直接返回新节点,避免额外的变量
        }
        
        TreeNode* cur = root;
        TreeNode* parent = nullptr; // 初始化 parent 为 nullptr,因为根节点没有父节点
        while (cur != nullptr) {
            parent = cur;
            if (cur->val > val) {
                cur = cur->left;
            } else {
                cur = cur->right;
            }
        }
        
        TreeNode* newNode = new TreeNode(val);
        if (val < parent->val) {
            parent->left = newNode;
        } else {
            parent->right = newNode;
        }
        
        return root;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KeepCoding♪Toby♪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值