【Leetcode二叉搜索树的修改与构造一】701. 二叉搜索树中的插入操作(有清晰的画图解析复杂递归过程,关于递归返回值的解法解析,二叉搜索树不回溯的理解!!!)

Leetcode701

1.问题描述

在这里插入图片描述

2.解决方案

解法一:有返回值递归

1.递归因为是二叉搜索树自然不需要全树遍历,只需要根据大小确定递归方向这个很好理解
2.但是说实话这个递归过程的话,需要理解一下,其实我们之前的二叉树递归都不需要创造新的结点自然也不需要结点与结点之间的赋值,但是这个需要把插入的节点赋给其父亲节点,所以就出现了这样的递归过程

//if(val>root->val) return insertIntoBST(root->right,val);
//if(val<root->val) return insertIntoBST(root->left,val);
if(val>root->val) root->right=insertIntoBST(root->right,val);
if(val<root->val) root->left=insertIntoBST(root->left,val);

在这里插入图片描述

3.这个递归过程理解好了,这道题就基本没啥事情了!


class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(root== nullptr){
            TreeNode* node=new TreeNode(val);
            return node;
        }

        //if(val>root->val) return insertIntoBST(root->right,val);
        //if(val<root->val) return insertIntoBST(root->left,val);
        if(val>root->val) root->right=insertIntoBST(root->right,val);
        if(val<root->val) root->left=insertIntoBST(root->left,val);

        //百分之百不会从这走
        //return nullptr;

        return root;
    }
};



解法二:无返回值递归

无返回值递归函数照样可以解决问题,这告诉我们问题永远有一般性的解法,各种解法都是可以的而不是看题解,每个题有每个题的解法,实则我们应该掌握的是所有题一种思路都可以解出来的理解程度!

1.无返回值递归就需要记录上一个节点parent,遇到空节点,就让parent的左/右孩子指向新节点并直接结束递归!
2.有两种写法,一种是把父节点写入递归函数参数,一种是变成全局,感觉参数更好理解一点
3.全局我一开始觉得有冲突问题也就是需要回溯不然肯定是错的,但是一想发现想多了,这是二叉搜索树,最终只会沿着一个方向进行下去,所以也不会有回溯的,但是如果有回溯全局就得多一步回溯,但是参数就不需要了因为是隐式回溯,如果回溯基础好的应该一下就明白了!

class Solution {
public:
    void tran(TreeNode* root,TreeNode* parent,int val){
        if(root== nullptr){
            TreeNode* node=new TreeNode(val);
            if(parent->val>val) parent->left=node;
            if(parent->val<val) parent->right=node;
            return;
        }

        if(val>root->val) tran(root->right,root,val);
        if(val<root->val) tran(root->left,root,val);
    }
    TreeNode* insertIntoBST(TreeNode* root, int val) {
    	//这一行必须有,不然上面的tran函数就得处理parent==nullptr&&root==nullptr的情况了
        if(root== nullptr) return new TreeNode(val);
        tran(root, nullptr,val);
        return root;
    }
};
class Solution {
public:
    TreeNode* parent= nullptr;
    void tran(TreeNode* root,int val){
        if(root== nullptr){
            TreeNode* node=new TreeNode(val);
            if(parent->val>val) parent->left=node;
            if(parent->val<val) parent->right=node;
            return;
        }
        
        parent=root;
        if(val>root->val) tran(root->right,val);
        if(val<root->val) tran(root->left,val);
    }
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        //这一行必须有,不然上面的tran函数就得处理parent==nullptr&&root==nullptr的情况了
        if(root== nullptr) return new TreeNode(val);
        tran(root,val);
        return root;
    }
};



解法三:迭代

迭代呢技巧就是记录parent和cur,找到插入点也就是cur==nullptr时,插入并返回根节点root
为什么好多题的迭代不给出了,这道题还是给出了是因为这是个还不错的记录前节点的迭代,若不是递归的翻版!

class Solution3 {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(root== nullptr) return new TreeNode(val);

        //开始寻找插入点
        TreeNode* parent=root;
        TreeNode* cur=root;
        while(cur!= nullptr){
            parent=cur;
            if(cur->val>val) {cur=cur->left; continue;}
            if(cur->val<val) {cur=cur->right; continue;}
        }

        //走到这说明cur==nullptr
        TreeNode* node=new TreeNode(val);
        if(parent->val>val) parent->left= node;
        if(parent->val<val) parent->right= node;

        return root;
    }
};
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值