【发布时间】:2021-10-25 15:10:00
【问题描述】:
问题:为什么我们希望BUILD-MAX-HEAP第2行的循环索引i从⌊length[A]/2⌋减少到1而不是从1 增加到@ 987654334@?
算法:(由《算法简介》一书提供):
我尝试使用以下图纸来展示这一点。
方法 1:如果我们以相反的方式将构建堆从 1 应用到数组 A = <5,3,17,10,84> 的 ⌊length[A]/2⌋,我们会:
方法 2:如果我们从 ⌊length[A]/2⌋ 以相反的方式应用构建堆并减少到数组 A = <5,3,17,10,84> 的 1,我们将:
问题:我看到在这两种情况下,父级大于其子级的堆属性都得到了维护,所以我不明白为什么一个解决方案会说会有这样的问题, “我们将不允许调用 MAX-HEAPIFY,因为它会使子树成为最大堆的条件失败。也就是说,如果我们以 1 开头,则无法保证A[2] 和 A[3] 是最大堆的根。”
【问题讨论】:
-
MAX-HEAPIFY 利用了 LEFT 和 RIGHT 都是有效堆这一事实。如果您以
i=1开头,则该假设无效。在 MAX-HEAPIFY(A, 1) 之后,A[1] 中的值要么是 A[1],要么是 A[2],要么是 A[3],并且以后的任何迭代都不会更改该值。但是堆中的最大值可能不是前三个之一。在您的示例中,第一个 MAX-HEAPIFY(A, 1) 产生 ,之后没有任何变化 A[1],所以根是 17。我不知道 84设法在您的方法 1 图中到达那里。 -
@RaymondChen。很明确的答案。我假设我是实时插入数组,所以每次添加新元素时我都会Heapify,这和你说的基本相同,所以我没有意识到我在方法1中使用Heapify Up方法. 在第二种方法中,我在插入所有元素后进行了 Heaify。所以两者都是基于 Heapify Up 的事实,所以我什至没有关注问题中提出的 Heapify。
-
如果您一次插入一个元素,那么这是一种不同的算法。 BUILD-MAX-HEAP 用于从非堆数组创建堆。如果您想将单个元素添加到已经有效的堆中,这是一个不同的操作,可能称为 INSERT-HEAP 之类的操作。一次添加一个项目是discussed here。