力扣题目——700. 二叉搜索树中的搜索

本文介绍了如何在JavaScript中实现插入值到二叉搜索树(BST)的操作,包括递归和迭代两种方法。通过理解二叉搜索树的性质,可以找到合适的位置插入新节点,保持树的有序性。示例展示了不同情况下插入节点的过程,并提供了详细的解题思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注:本文的代码实现使用的是 JS(JavaScript),为前端中想使用JS练习算法和数据结构的小伙伴提供解题思路。

题目描述

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

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


输入示例

示例1

输入: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 和 10^4 之间
  • 每个节点都有一个唯一整数值,取值范围从 0 到 10^8
  • −108<=val<=108-10^8 <= val <= 10^8108<=val<=108
  • 新值和原始二叉搜索树中的任意节点值都不同

解题思路

二叉搜索树的性质,对任意子树的根节点,都有:左子树根节点的值小于当前根节点的值,右子树根节点的值大于当前根节点的值。代码中一些地方是可以简写的,比如if(root === null)的效果等价于if(!null),只不过为了能够清晰地表达出思路,所以并未简化。

1. 递归版

其实对于二叉搜索树来说,新的节点可以插入到叶节点的下面,不必在中间插入。因此,只需要搜索到合适的叶节点(比较根节点与val的大小,根小于val,搜索右子树;大于,则搜索左子树),最后比较要插入的值和叶节点的值大小决定是成为该叶节点的左节点还是右节点,即:

  • 如果该子树不为空,则问题转化成了将 val插入到对应子树上。
  • 否则,在此处新建一个以val为值的节点,并链接到其父节点root上。
var insertIntoBST = function(root, val) {
	// 这个 if 语句有两个作用
	// 1. 初始时给定一棵空树,则创建节点并返回
	// 2.遍历到符合要求的叶子节点位置,创建节点
    if(root === null) return new TreeNode(val)
    // 开始递归遍历
    else {
    	// 注意,这里一定要将函数的返回值赋值给对应根节点的 left 或 right
    	if(root.val > val)
    		// 根节点的数值大于目标节点的数值,则向左子树中寻找合适的插入位置
    		root.left = insertIntoBST(root.left, val) 
    	else
    		// 根节点的数值小于目标节点的数值,则向右子树中寻找合适的插入位置
    		root.right = insertIntoBST(root.right, val)
    }
    // 不论该根节点的左右子树是否发生变化,均需要返回该根节点
    return root
};
2. 迭代版

我们也可以使用迭代的方式去找到适合插入的位置。

var insertIntoBST = function(root, val) {
	// 创建需要插入的节点
    insertNode = new TreeNode(val)
    // 初始时给定一棵空树,则返回创建的节点
    if(root === null) return insertNode
    // 根指针的拷贝,若直接使用root进行搜索,则最后返回的那棵树的根节点就找不到了
    let node = root
    //迭代
    while(node !== null){
    	// 目标值小于当前节点值,则向左子树中寻找合适的插入位置
        if(val < node.val){
        	// 左子树为空,则插入该节点
            if(node.left === null){
                node.left = insertNode
                // 不要忘记退出循环,节点都插完了,还遍历的啥劲
                break
            }
            else
            	// 左子树不为空,接着遍历左子树
                node = node.left
        }
        // 目标值大于当前节点值,则向右子树中寻找合适的插入位置
        else{
        	// 右子树为空,则插入该节点
            if(node.right === null){
                node.right = insertNode
                break
            }
            else
            	// 右子树不为空,接着遍历右子树
                node = node.right
        }
    }
    // 返回插入后的树
    return root
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值