为什么我们从下向上而不是从上到下构建最大堆

Why we build max heap from bottom up instead from top bottom

问题:为什么我们要BUILD-MAX-HEAP第2行的循环索引i⌊length[A]/2⌋减少到1 而不是从 1 增加到 ⌊length[A]/2⌋?

算法:(算法导论书提供):

我试着用下面的图来展示这个。

方法 1:如果我们以相反的方式应用构建堆,从数组 A = <5,3,17,10,84>1 ⌊length[A]/2⌋,我们将有:

方法 2:如果我们以与 ⌊length[A]/2⌋ 相反的方式应用构建堆并减少到数组 A = <5,3,17,10,84>1,我们将有:

问题:我看到在这两种情况下,父项大于其子项的堆 属性 得到维护,所以我不明白为什么解决方案说会出现这样的问题,“我们将不允许调用 MAX-HEAPIFY,因为它会使子树成为最大堆的条件失败。也就是说,如果我们从 1 开始,则无法保证 A[2]A[3] 是最大堆的根。“

当以 i 为根的子树服从堆 属性 到处 除了 可能是根值(在 ​​i)本身,这可能需要筛选。 MAX_HEAPIFY的工作只是将根的值移动到正确的位置。它无法修复堆的任何其他违规行为 属性。但是,如果保证 i 下面的树的其余部分服从堆 属性,那么你可以确定 i[ 的子树=43=] 将在 MAX_HEAPIFY 具有 运行.

之后成为一个堆

所以如果你从顶部节点开始,那么谁知道你会得到什么......树的其余部分预计不会服从堆 属性,所以 MAX_HEAPIFY 不会(必然)交付一堆。以自上而下的方式继续工作也无济于事。

如果我们采用示例树并执行 forward 循环替代方案,那么我们从调用此树上的 MAX_HEAPIFY(1) 开始:

       5
      / \
     3   17
    / \
  10   84

...然后 5 将与 17 交换(在位置 3),然后我们将在该节点上递归调用 MAX_HEAPIFY(3),这什么都不做。所以我们会得到:

       17
      / \
     3   5
    / \
  10   84

接下来,我们调用 MAX_HEAPIFY(2) 将 3 与 84 交换:

       17
      / \
     84  5
    / \
  10   3

再次对值为 3 的节点进行递归调用,但这不会执行任何操作。

这是 forward 循环替代中 MAX_HEAPIFY 的最后一次调用...我们可以看到值 84 没有机会找到所有路径通往它所属的顶部的方式。