如何从堆中删除根节点?

时间:2019-06-26 21:01:51

标签: tree binary heap

我有一个堆:90 80 80 40 10 2050。我必须删除根节点3次。它会取代什么叶子?

我尝试删除90个根节点并将其替换为50,因为它位于堆的最后位置。但我也看到可以用40代替它,因为它是最后一个孩子。哪种解决方案是正确的?

3 个答案:

答案 0 :(得分:0)

将其替换为50是正确的,因为它保留了从上到下,从左到右完整的堆结构的属性。

完整二叉树是一种二叉树,其中所有级别(可能除了最后一个级别)都已完全填充,并且所有节点都尽可能地向左移。
因此,删除最右边的位将使树尽可能地向左移。

答案 1 :(得分:0)

从二进制堆中删除根节点的规则是:

  1. 将根节点替换为堆中最低的,最右边的项目。
  2. 减少计数。
  3. 将新值向下筛选到新位置。

例如,给定数组[90, 80, 80, 40, 10, 20, 50],您将拥有堆:

            90
        80      80
      40  10  20  50

您删除90,然后替换为50,这样:

            50
        80      80
      40  10  20

现在,您进行筛选。筛选的规则是交换两个孩子中最大的一个。在这种情况下,两个孩子是相等的,因此您可以交换其中一个。无论哪种方式,结果都是有效堆。 80在顶部,而下一级的两个节点是[80,50],或者是[50,80]。

选择最低,最右边的项目的原因是为了维护堆属性。请记住:堆是一棵完整的二叉树,所有级别都完全填满,除了最后一个级别(左端是空的)。让我向您展示一个稍有不同的堆,这可能会导致问题:

         90
     66      74
   65  11  70  50

现在,如果要用65代替90,那么第一个问题就是阵列中有孔。也就是说,您将拥有[65, 66, 74, __, 11, 70, 50]。通过将超出空白区域的所有内容移至左侧,从而给您[65, 66, 74, 11, 70, 50],可以轻松解决该问题。但是现在让我们将其视为堆:

         65
     66      74
   11  70  50

筛选的规则说,您必须与最大的孩子交换。在这种情况下为74。但是,如果这样做,最终将导致此无效堆:

         74
     66      65
   11  70  50

您不能只是决定与较小的孩子交换,因为如果您这样做,则66将是根。无论哪种方式,您最终都会得到无效的堆。

将根替换为最低的,最右边的节点(数组中的最后一项)有两个原因:

  1. 正确性。通过删除最后一项,可以保证不影响任何其他节点的关系。从其他任何地方删除都会使堆无效。
  2. 效率。从数组中删除最后一项很简单。从其他任何地方删除都可能是O(n)操作。

答案 2 :(得分:0)

根据定义,二进制堆是完整的二进制树。这意味着:

  1. 每个节点有两个孩子或者是一片叶子。
  2. 除了可能的最后一层之外,所有树的级别均已完全填充
  3. 如果最后一个级别未完成,则该级别的节点从左到右填充

在您的示例中,如果要删除最左边的叶子(40),则不再保持第三个条件:现在,最后一个级别的最左端有一个缝隙。

您可以删除 而不会破坏这三个条件中任何一个的唯一节点是最右边的叶子。换句话说,这是您可以删除的唯一节点,以达到最终结果应具有的树形。

这就是为什么您需要将根节点(要删除的根节点)替换为节点50(取而代之的是,其值将覆盖原始根值)。