返回
程序员必刷题LeetCode450 删除二叉搜索树中的节点详解
前端
2023-11-29 00:36:22
问题
给定一个二叉搜索树的根节点 root 和一个值 key,要求我们删除树中与 key 对应的节点。同时保证操作完后,树仍然是一个二叉搜索树,即维持其性质不变。
解决方案
题目要求算法时间复杂度为 O(h),其中 h 为树的高度,这说明了解决方案必须是在树中搜索到 key 所在的节点,然后执行适当的操作来删除该节点及其子节点。
针对本题,我们可以采用迭代或递归两种方式。
-
迭代解法:
- 从根节点 root 开始迭代搜索,依次遍历所有节点,直到找到要删除的节点 key。
- 当找到 key 时,将其删除,并考虑以下情况:
- 若 key 节点是叶子节点,则直接将其删除。
- 若 key 节点只有左子节点或右子节点,则用其子节点代替 key 节点的位置。
- 若 key 节点同时拥有左子节点和右子节点,则需要找出 key 节点的前驱或后继节点,并用它替换 key 节点的位置,然后删除前驱或后继节点。
- 在本方法中,我们选择使用前驱节点来替换 key 节点,因为其值一定小于 key,且仍然符合二叉搜索树的性质。
- 删除节点后,调整树的结构,确保其仍然是一个二叉搜索树。
-
递归解法:
- 从根节点 root 开始进行递归调用,依次遍历所有节点,直到找到要删除的节点 key。
- 当找到 key 时,将其删除,并考虑与迭代解法相同的几种情况:
- 若 key 节点是叶子节点,则直接将其删除。
- 若 key 节点只有左子节点或右子节点,则用其子节点代替 key 节点的位置。
- 若 key 节点同时拥有左子节点和右子节点,则需要找出 key 节点的前驱或后继节点,并用它替换 key 节点的位置,然后删除前驱或后继节点。
- 删除节点后,递归地调整树的结构,确保其仍然是一个二叉搜索树。
复杂度分析
无论是迭代解法还是递归解法,其时间复杂度均为 O(h),其中 h 为树的高度,因为在最坏情况下,需要遍历整棵树才能找到要删除的节点。
示例
考虑以下二叉搜索树:
10
/ \
5 15
/ \ / \
2 8 12 20
如果我们要删除节点 8,那么根据我们的算法,我们首先从根节点 10 开始搜索,依次访问 5、2、8。当找到节点 8 后,由于它有一个左子节点和一个右子节点,我们需要找到其前驱节点或后继节点,我们选择前驱节点 5,并将其与节点 8 的右子节点相连接。
删除节点 8 后,我们得到以下二叉搜索树:
10
/ \
5 15
/ \ / \
2 6 12 20
可以看出,二叉搜索树的性质依然保持不变。
结语
删除二叉搜索树中的节点是LeetCode题库中一道经典的题目。通过这道题的讲解,读者可以熟悉二叉搜索树的基本性质和操作,并掌握迭代和递归两种解题方法。这些知识对于程序员来说非常重要,因为二叉搜索树在实际开发中经常被用来存储和管理有序数据。