701. 二叉搜索树中的插入操作
题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/insert-into-a-binary-search-tree
题目
给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据保证,新值和原始二叉搜索树中的任意节点值都不同。
注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回任意有效的结果。
例如,
给定二叉搜索树:
4
/ \
2 7
/ \
1 3
和 插入的值: 5
你可以返回这个二叉搜索树:
4
/ \
2 7
/ \ /
1 3 5
或者这个树也是有效的:
5
/ \
2 7
/ \
1 3
\
4
提示:
- 给定的树上的节点数介于
0
和10^4
之间 - 每个节点都有一个唯一整数值,取值范围从
0
到10^8
-10^8 <= val <= 10^8
- 新值和原始二叉搜索树中的任意节点值都不同
解题思路
思路:递归、迭代
本站中的 700. 二叉搜索树中的搜索 这道题是希望能够在二叉搜索树上查找指定节点。有兴趣的话,可以尝试下。
而本题,是希望在二叉搜索树上插入指定的节点。
先看看题目中给出的提示:
- 待插入树中的新值,与原始二叉搜索树的任意节点值都不同,也即是可以不用考虑值相等的情况;
- 插入方式有多种,只要符合插入节点后仍为二叉搜索树,那么可返回任意一种有效的结果(本篇主要采用的是示例中的第一种插入形式);
- 给定的树节点数介于
0
和10^4
之间,那么有可能存在空树的情况。
现在,我们先说下二叉搜索树(BST)的定义(可能读者已经都知道了,我这里为了文章的完整性,就再赘述一遍):
- 结点左子树中所含结点的值小于等于当前结点的值
- 结点右子树中所含结点的值大于等于当前结点的值
- 左子树和右子树都是二叉搜索树
那么根据二叉搜索树(BST)的定义,我们可以发现这里只要比较 待插入树中的值 和根节点的值,就能够有效的缩小范围。
在这里,我们可以使用递归或迭代的方法来实现。
递归
这里先看使用递归的具体方法:
- 当根节点为空时,直接新建树节点作为根节点返回;
- 当根节点不为空时,需要比较 root 的节点值与给定待插入树中的值 val:
- 如果 root.val > val,那么 val 应该插入 root 的左子树中,那么此时应该往左子树方向找插入位置;
- 如果 root.val < val,那么 val 应该插入 root 的右子树中,那么此时应该往右子树方向查找插入位置。
具体的代码实现如下。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
node = TreeNode(val)
def dfs(root, val):
# 当根节点不存在时,返回新建树节点
if not root:
return node
# 如果 root.val < val,说明 val 应该插入 root 的右子树,往 root 的右子树方向继续找位置
if root.val < val:
root.right = dfs(root.right, val)
# 否则 val 应该插入左子树,往 root 的左子树方向继续查找位置
else:
root.left = dfs(root.left, val)
return root
return dfs(root, val)
迭代
我们也可以使用迭代的方法,同样是比对 root 的节点值与待插入树中的值,缩小范围。具体做法如下:
- 当根节点为空时,返回新建树节点;
- 当根节点不为空时,首先定义变量 cur,指向 root(这里 cur 用于后面迭代更换指向,不至于影响 root)
- 当 cur.val > val 时,则说明 val 应该插入 cur 的左子树中。此时需要判断 cur.left 是否为空,若为空,将新建树节点插入此处,跳出循环,返回 root;否则令 cur = cur.left,往左子树方向继续查找;
- 当 cur.val < val 时,则说明 val 应该插入 cur 的右子树中。此时需要判断 cur.right 是否为空,若为空,将新建树节点插入此处,跳出循环,返回 root;否则令 cur = cur.right,往右子树方向继续查找。
具体的代码实现如下:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
node = TreeNode(val)
# 根节点为空,直接将新建树节点返回
if not root:
return node
# 定义变量 cur 指向 root
cur = root
# 循环遍历开始
while True:
# 当 cur.val > val,说明 val 应该在 cur 的左子树插入
if cur.val > val:
# 如果 cur 左子树为空,将新建树节点插入此处,跳出循环
if not cur.left:
cur.left = node
break
# 否则往左子树方向继续查找
cur = cur.left
# cur.val < val,说明 val 应该在 cur 的右子树插入
else:
# cur 右子树为空,将新建树节点插入此处,跳出循环
if not cur.right:
cur.right = node
break
# 否则继续往右子树的方向查找
cur = cur.right
return root
欢迎关注
公众号 【书所集录】
如有错误,烦请指出,欢迎指点交流。