前言
又是学习LeetCode二叉树的新一天,今天还是继续学习一下二叉搜索树的内容,二叉树的基本内容快学习的差不多啦,希望博主记录的内容能够对大家有所帮助 ,一起加油吧朋友们!💪💪💪
二叉搜索树中的插入操作
LeetCode题目链接
给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 插入的值和原始二叉搜索树中的任意节点值都不同 。

思路梳理🤔🤔
- 题目中虽然提到了存在多种有效的插入方式,但是我们可以就以遍历找到对应位置插入节点即可🤔
递归三要素梳理🤔🤔
1 2 3
|
public TreeNode insertIntoBST(TreeNode root, int val) {}
|
1 2 3 4 5
| if(root == null){ TreeNode node = new TreeNode(val); return node; }
|
1 2 3 4 5 6 7
| if(root.val > val){ root.left = insertIntoBST(root.left, val); }else if(root.val < val){ root.right = insertIntoBST(root.right, val); } return root;
|
有返回值的总的递归代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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); }else if(root.val < val){ root.right = insertIntoBST(root.right, val); } return root; } }
|
- 而没有返回值则需要有一个变量来记录每一次遍历的节点的父结点,当往下一层处理时就可以对父结点的左右子节点进行插值操作🤔,无返回值的递归方法如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Solution { TreeNode parent = new TreeNode(0); public TreeNode insertIntoBST(TreeNode root, int val) { if(root == null){ root = new TreeNode(val); } traversal(root, val); return root; }
private void traversal(TreeNode root, int val){ if(root == null){ TreeNode node = new TreeNode(val); if(parent.val > val){ parent.left = node; }else{ parent.right = node; } return ; }
parent = root; if(root.val > val)traversal(root.left, val); if(root.val < val)traversal(root.right, val); return ; } }
|
- 而迭代法同理就是也要记录遍历节点的父结点进行记录追踪,然后循环找到遍历位置后对父结点进行插值操作🤔,迭代方法代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public TreeNode insertIntoBST(TreeNode root, int val) { if(root == null){ TreeNode node = new TreeNode(val); return node; }
TreeNode parent = root; TreeNode cur = root; while(cur != null){ parent = cur; if(cur.val > val) cur = cur.left; else cur = cur.right; } TreeNode node = new TreeNode(val); if(val > parent.val) parent.right = node; else parent.left = node; return root; } }
|
删除二叉搜索树中的节点
LeetCode题目链接
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。 返回二叉搜索树的根节点。
我们来梳理一下思路🤔🤔,我们重点就要搞清楚单层处理逻辑
- 第一种情况:递归没找到要删除的节点,遍历到空节点直接返回了

- 第二种情况:找到要删除的节点并且节点是叶子节点,直接删除返回根节点null


- 第五种情况:左右孩子都不为空,则将删除节点的左子树作为删除节点右子树的最左节点的左孩子🤔🤔

我们来梳理一下递归三要素🤔🤔
1 2
| public TreeNode deleteNode(TreeNode root, int key) {}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| if(root == null) return root; if(root.val == key){ if(root.left == null && root.right == null) { return null; } else if(root.left == null){ return root.right; } else if(root.right == null){ return root.left; }else{ TreeNode node = root.right; while(node.left != null){ node = node.left; } node.left = root.left; root = root.right; return root; } }
|
1 2 3 4
| if(root.val > key) root.left = deleteNode(root.left, key); if(root.val < key) root.right = deleteNode(root.right, key); return root;
|
迭代法的话有点复杂这里我们就不写了,感兴趣的话大家自己可以写一下🫡🫡🫡
修剪二叉搜索树
LeetCode题目链接
给一个二叉树并指定最小数值边界和最大数值边界,通过修剪二叉树使得二叉树的所有节点值在这个闭区间中,返回修剪好的二叉搜索树的根节点。

我们来思路梳理一下🤔🤔
- 从上图中可以看到如果单纯去判断
if(root.val <low || root >high) return null 的话,则上图中修剪区间[5,10]的时候就只能剪出一个8了,所以这该怎么处理呢?🤔🤔就是在上图中修剪区间为[5,10]时如果剪掉0节点的时候它的右孩子不为空就也需要修剪,我们将其右孩子连接上其父结点继续修剪即可😮😮
我们进一步来梳理递归三要素
1 2 3
|
TreeNode trimBST(TreeNode root, int low, int high){}
|
1 2
| if(root == null)return null;
|
1 2 3 4 5 6 7 8 9 10 11 12
| if(root.val < low){ TreeNode right = trimBST(root.right, low, high); return right; } if(root.val > high){ TreeNode left = trimBST(root.left, low, high); return left; }
root.left = trimBST(root.left, low, high); root.right = trimBST(root.right, low, high); return root;
|
递归完整代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public TreeNode trimBST(TreeNode root, int low, int high) { if(root == null)return null; if(root.val < low){ TreeNode right = trimBST(root.right, low, high); return right; } if(root.val > high){ TreeNode left = trimBST(root.left, low, high); return left; } root.left = trimBST(root.left, low, high); root.right = trimBST(root.right, low, high); return root; } }
|
我们来梳理下迭代法的处理方式🤔🤔
- 因为二叉搜索树是有序的,不需要用栈来存储节点。我们循环处理的话需要注意,因为涉及判断要不要把左孩子的右子树连接到上一层,所以相当于循环处理三层,首先找到一个边界内的头节点,然后修剪左孩子(相当于往小边界找,若找到比边界还小则把右孩子连接处理节点的父结点直到空节点),然后右孩子的修剪逻辑类似。

迭代代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Solution { public TreeNode trimBST(TreeNode root, int low, int high) { if(root == null)return null; while(root != null && (root.val < low || root.val > high)){ if(root.val < low)root = root.right; else root = root.left; } TreeNode node = root; while(node != null){ while(node.left != null && node.left.val < low){ node.left = node.left.right; } node = node.left; } node = root;
while(node != null){ while(node.right != null && node.right.val > high){ node.right = node.right.left; } node = node.right; } return root; } }
|
总结
二叉树的内容基本就要学习的差不多了,还剩下一些,我们继续加油,后面开始回溯的基本内容的学习✊✊✊