本题也是在面试中遇到的一道算法题,今天我们来分析分析这道二叉树的题目。
题目描述
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
- 首先找到需要删除的节点;
- 如果找到了,删除它。
示例 1:
输入:root = [5,3,6,2,4,null,7], key = 3 输出:[5,4,6,2,null,null,7]
思路分析
题目说明了这是一颗二叉搜索数,我们应该想到利用二叉搜索树的特点(右子树总是大于左子
树),既然要删除节点,这里我们选择用递归的方法来遍历。如果当前节点的值<要删除的值,根
据二叉搜索树的特点我们就递归搜索它的右子树;如果当前节点的值>要删除的值,就遍历左子
树;当前节点的值等于要删除的值时候,我们就执行删除操作。
递归操作
递归三步走:
1. 确定递归函数参数以及返回值
这里我们可以递归的返回值来删除节点
2. 确定终止条件
当我们递归遇到root==null时,返回root,表示没有找到该节点
3. 单层递归的逻辑实现
这里又分为五种情况讨论:
- 当删除节点左右孩子都为空时,直接删除该节点
- 当要删除的节点不存在时,返回root
- 当删除节点的左孩子不为空,右孩子为空时,直接就返回左孩子节点
- 当删除节点的右孩子不为空,左孩子为空时,直接就返回右孩子节点
- 当删除节点的左孩子和右孩子都存在时,调整树的结构(最复杂);
五种情况中,前四种都不用改变树的结构相对容易,下面我们来详细分析第五种情况:
假设我们要删除树中的元素8
我们先定义节点cur指向要root.right;然后遍历cur的左子树,直到左子树为null,这样我们就可以
把要删除节点的左子树进行转移,接到cur的左子树;在图中就是,一直遍历10节点的左子树,
直到为null(确保是10左边的最小节点),然后我们把节点8的左子树接过去,这样可以保证删除
后还是一颗二叉搜索树。
完整代码
总结
这就是本道题全部讲解啦,小伙伴们觉得难度怎么样呢?