二叉搜索树(BST)的查找、插入与删除操作
字数 2051 2025-11-03 00:19:05
二叉搜索树(BST)的查找、插入与删除操作
二叉搜索树是一种特殊的二叉树,它满足以下性质:对于树中的任意节点,其左子树中所有节点的值都小于该节点的值,其右子树中所有节点的值都大于该节点的值。这个性质使得二叉搜索树在查找、插入和删除操作上非常高效。
1. 查找操作
-
目标:在二叉搜索树中查找一个特定的值。
-
过程:利用BST的性质,我们可以快速缩小搜索范围。
- 从根节点开始:将目标值与根节点的值进行比较。
- 如果相等:恭喜,查找成功。
- 如果目标值小于根节点的值:说明目标值只可能存在于根节点的左子树中(如果存在的话)。于是,我们递归地在左子树中继续查找。
- 如果目标值大于根节点的值:说明目标值只可能存在于根节点的右子树中。于是,我们递归地在右子树中继续查找。
- 遇到空节点:如果在查找过程中,我们根据比较结果需要进入一个子节点,但这个子节点是空的(
null),则说明树中不存在我们要找的值,查找失败。
-
示例:在下图的BST中查找值
8。10 / \ 5 15 / \ / \ 3 7 12 18 / 8- 从根节点
10开始,8 < 10,进入左子树。 - 当前节点是
5,8 > 5,进入右子树。 - 当前节点是
7,8 > 7,进入右子树。 - 当前节点是
8,相等,查找成功。
- 从根节点
2. 插入操作
-
目标:将一个不存在于树中的新值插入到BST的正确位置,并保持BST的性质。
-
过程:插入操作与查找操作非常相似。我们首先要找到新节点应该被放置的位置。这个位置必然是某个叶子节点的空子节点位置。
- 从根节点开始比较:将新节点的值与当前节点比较。
- 如果新值小于当前节点的值:
- 如果当前节点的左子节点为空,就将新节点作为左子节点插入。
- 如果左子节点不为空,则递归地在左子树中继续执行插入操作。
- 如果新值大于当前节点的值:
- 如果当前节点的右子节点为空,就将新节点作为右子节点插入。
- 如果右子节点不为空,则递归地在右子树中继续执行插入操作。
- 注意:如果新值等于当前节点的值,根据具体实现,可以选择不允许重复值(忽略插入),或将新节点插入为右子节点(或左子节点)等。通常BST不包含重复值。
-
示例:向一个空树中依次插入
10, 5, 15, 3, 7, 12, 18, 8,最终形成的树就是上面示例中的树。
3. 删除操作
-
目标:从BST中删除一个指定的节点,并保持BST的性质。这是三个操作中最复杂的一个,因为被删除的节点可能有零个、一个或两个子节点。我们需要分三种情况讨论。
-
过程:
- 定位要删除的节点:首先,使用查找算法找到要删除的节点,记为
node。 - 根据
node的子节点情况处理:-
情况一:
node是叶子节点(没有子节点)- 这是最简单的情况。直接将其父节点指向它的指针设置为
null即可。 - 示例:删除节点
3。只需将节点5的左指针设为null。
- 这是最简单的情况。直接将其父节点指向它的指针设置为
-
情况二:
node只有一个子节点- 让
node的父节点绕过node,直接指向node的唯一那个子节点。 - 示例:删除节点
7(它有一个左子节点8)。- 找到节点
7的父节点5。 - 让
5的右指针(原来指向7)改为指向7的左子节点8。 - 这样,节点
7就被从树中移除,它的子节点8接替了它的位置。
- 找到节点
- 让
-
情况三:
node有两个子节点- 这是最复杂的情况。我们不能简单地删除它,因为会留下两个子树需要连接。我们的策略是:
a. 寻找替代者:在node的右子树中,找到值最小的节点(这个节点称为node的中序遍历后继节点)。根据BST的性质,这个节点是大于node值的最小节点。同样,你也可以选择node的左子树中值最大的节点(中序遍历前驱节点)。
b. 复制值:将找到的这个后继节点(或前驱节点)的值复制到node中,覆盖掉node原来的值。
c. 删除后继节点:现在,问题转化为删除那个后继节点(或前驱节点)。而这个节点最多只有一个子节点(因为它是右子树中的最小节点,所以它不可能有左子节点;同理,左子树的最大节点不可能有右子节点),这就回到了情况一或情况二,我们可以轻松删除它。 - 示例:删除根节点
10。- 节点
10有两个子节点。 - 在它的右子树(以
15为根)中寻找最小的节点。这个节点是12(它没有左子节点)。 - 将
10的值替换为12。 - 现在,原树中出现了两个
12。我们需要删除右子树中原来的那个12。这个节点只有一个右子节点(或者没有,本例中没有),按照情况二删除它即可。最终,树的结构仍然满足BST的性质。
- 节点
- 这是最复杂的情况。我们不能简单地删除它,因为会留下两个子树需要连接。我们的策略是:
-
- 定位要删除的节点:首先,使用查找算法找到要删除的节点,记为
通过掌握查找、插入和删除这三个核心操作,你就掌握了二叉搜索树的基本工作原理。这些操作的平均时间复杂度都是 O(log n),其中 n 是树中节点的个数,这使得BST成为一种非常实用的数据结构。