当前位置: 首页 > 知识库问答 >
问题:

使用递归删除二进制搜索树

郑燕七
2023-03-14

从二叉查找树中删除节点时,您可以将节点替换为左侧的最大子节点或右侧的最小子节点。

我很难理解以下实现执行删除操作的方式。

@discardableResult public func remove() -> BinarySearchTree? {
  let replacement: BinarySearchTree?

  // Replacement for current node can be either biggest one on the left or
  // smallest one on the right, whichever is not nil
  if let right = right {
    replacement = right.minimum()
  } else if let left = left {
    replacement = left.maximum()
  } else {
    replacement = nil
  }

  // Recursion
  replacement?.remove()

  // Place the replacement on current node's position
  replacement?.right = right
  replacement?.left = left
  right?.parent = replacement
  left?.parent = replacement
  reconnectParentTo(node:replacement)

  // The current node is no longer part of the tree, so clean it up.
  parent = nil
  left = nil
  right = nil

  return replacement
}

上面的代码包括以下步骤:

    < li >查找替换节点。 < li >让替换节点引用已删除节点的左右子节点。 < li >让已删除节点的左右子节点将替换节点作为父节点。 < li >让替换节点引用已删除节点的父节点作为自己的父节点。 < li >清理。

我有困难的部分特别是递归。据我所知,递归的基本情况是替换=nil,因为只要有右子或左子,递归就会继续发生。然而,当替换应该引用替换节点时,它怎么能是nil?同时,如果替换不是nil,递归如何停止?

共有1个答案

吕永嘉
2023-03-14

它可能有助于直观地看到发生了什么。假设您从这棵树开始,并希望删除橙色根节点

在橙色节点上调用remove

    < li> self为橙色。 < li> replacement是右边子树(蓝色节点)的最小值。

通过在蓝色上调用remove来递归:

    < li> self是蓝色的 < li> replacement为零,因为blue既没有左子系也没有右子系 < li >您在< code>nil上调用< code>remove(或者说您没有调用,因为?) < li >同样,跳过所有其他赋值,因为可选值都是< code>nil 调用< Li > < code > reconnect parent(node:nil)来修复blue的父对象的左/右链接(这将导致< code>green.left被赋值为< code>nil) < li >您返回蓝色

树现在如下所示:

现在,您在最初调用< code>remove时退出,执行继续。记住,

  • 自我是橙色的。
  • 替换是蓝色节点。

接下来的步骤是:

  • <代码>蓝色。右=橙色。右
  • <代码>蓝色。left=橙色。左
  • orange.right。父级=蓝色
  • orange.left。父级=蓝色
  • <代码>橙色。reconnectParentTo(节点:蓝色)-这不起作用,因为橙色没有父级
  • <代码>橙色。父级=nil
  • <代码>橙色。右=无
  • <代码>橙色。左=零
  • remove返回-这是对remove的初始调用,因此我们退出了所有递归

这给我们留下了最后一棵树:

 类似资料:
  • 问题内容: 我知道Go有一个包含搜索功能的程序包,但这是出于教育目的。我一直在尝试在Go中实现二进制搜索算法,但无法使其正常工作。 这是我的代码: 它总是打印。为什么? 问题答案: 二进制搜索的逻辑是合理的。唯一的问题是您忘记了将每个递归调用的结果分配给和。 当前,您有以下这些递归调用: 您只需要分配结果:

  • 我试着删除二叉查找树的节点,当我打印出来的时候,我得到的结果实际上不是这个删除,实际上可以删除二叉树本身的任何键。 我是二进制搜索树的新手。有人能帮我写代码吗?我们将感谢您的帮助。 谢谢 完整代码

  • 首先,这是家庭作业,所以把它放在外面。 我应该用特定的方法实现二叉查找树: void insert(字符串)、boolean remove(字符串)和boolean find(字符串)。 我已经能够成功地编程和测试插入,并找到方法,但我有困难与删除。 我的程序中发生的事情是,删除实际上并没有从树中删除任何东西,我相信这是因为它只引用当前节点的本地创建,但我可能错了。我认为我可以实现我需要测试的不同

  • 这是作业,不要贴代码。求你了,谢谢你。 我被指派创建一个计算BST中特定的深度的方法。 为此,我需要a方法。因此,要递归地找到它,我需要创建一个助手方法。 我知道我需要在树中搜索包含我要查找的数据的节点。为此,我编写了以下代码: 然而,这是行不通的,因为每次进行递归调用时,将保持;本质上,它是在重置深度值。我不知道如何在调用之间保持的值。

  • 我正在处理一个Path方法,它返回从给定节点到具有给定值键的节点的路径。我的代码返回正确的数字,但它们在括号内。我如何拆下支架? 实际输出为: 但它应该是:

  • 目前,我在理解如何在没有传递节点时从二进制搜索树中删除节点时遇到了一个问题。我有两个类,BSTSet和BSTNode,每个类都有一个remove方法。。 当我被传递一个节点时,我理解删除方法,但当我在根上调用remove方法并试图从node类中删除节点时,我不知道从何处开始。有人能告诉我吗?谢谢如果您想了解更多信息,请询问。