漫画:二叉树系列 第五讲(BST的删除)

在两节中,我们了解了BST(二叉搜索树)的概念,并且知道了如何在BST中查找一个元素。那我们又如何在BST中去删除一个元素呢?我们将通过本节的例题进行学习!

下面看题:????????????

01

第450题:二叉搜索树中的删除

第450题:给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

首先找到需要删除的节点;

如果找到了,删除它。

说明:要求算法时间复杂度为 O(h),h 为树的高度。

示例:

root = [5,3,6,2,4,null,7]

key = 3

    5

   / \

  3   6

 / \   \

2   4   7

给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。

一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。

    5

   / \

  4   6

 /     \

2       7

另一个正确答案是 [5,2,6,null,4,null,7]。

    5

   / \

  2   6

   \   \

    4   7

强烈建议先学习之前两节内容!

以达到最好的学习效果!

02

复习巩固

先复习一下,二叉搜索树(BST)的特性:

1.若它的左子树不为空,则所有左子树上的值均小于其根节点的值

2.若它的右子树不为空,则所有右子树上的值均大于其根节点得值

3.它的左右子树也分别为二叉搜索树

如下图就是一棵典型的BST:

03

图解分析

明确了概念,我们进行分析。我们要删除BST的一个节点,首先需要找到该节点。而找到之后,会出现三种情况。

  1. 待删除的节点左子树为空,让待删除节点的右子树替代自己。

  2. 待删除的节点右子树为空,让待删除节点的左子树替代自己。

  3. 如果待删除的节点的左右子树都不为空。我们需要找到比当前节点小的最大节点(前驱),来替换自己

    或者比当前节点大的最小节点(后继),来替换自己。

分析完毕,直接上代码。

04

代码如下


这里我们给出通过后继节点来替代自己的方案(请后面自行动手实现另一种方案):

 1//go
 2func deleteNode(root *TreeNode, key int) *TreeNode {
 3    if root == nil {
 4        return nil
 5    }
 6    if key < root.Val {
 7        root.Left = deleteNode( root.Left, key )
 8        return root
 9    }
10    if key > root.Val {
11        root.Right = deleteNode( root.Right, key )
12        return root
13    }
14    //到这里意味已经查找到目标
15    if root.Right == nil {
16        //右子树为空
17        return root.Left
18    }
19    if root.Left == nil {
20        //左子树为空
21        return root.Right
22    }
23    minNode := root.Right
24    for minNode.Left != nil {
25        //查找后继
26        minNode = minNode.Left
27    }
28    root.Val = minNode.Val
29    root.Right = deleteMinNode( root.Right )
30    return root
31}
32
33
34func deleteMinNode( root *TreeNode ) *TreeNode {
35    if root.Left == nil {
36        pRight := root.Right
37        root.Right = nil
38        return pRight
39    }
40    root.Left = deleteMinNode( root.Left )
41    return root
42}

注:本系列所有教程中都不会用到复杂的语言特性,大家不需要担心没有学过相关语法。算法思想最重要,使用各语言纯属本人爱好。同时,本系列所有代码均在leetcode上进行过测试运行,保证其严谨性!

学会了吗?

无论是不理解还是有别的解题思路都可以在评论区进行留言~

如果已完全掌握,一定记得点击右方“在看”进行每日打卡!

还没进群的小伙伴抓紧啦!

温馨提示

浩仔讲算法~

每天一起学习图解漫画算法。

一起刷题,一起成长!

~长按下方二维码进行关注吧~

关注后有资源~

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值