最大堆化算法

Max Heapify Algorithm

我有点困惑。如果我有一个数组,我必须构建一棵树。为了比较 childern 我必须知道我的数组有多大,在这种情况下它的 N = 6 所以我必须将它除以 2 所以我得到 3。这意味着我必须从索引 3 开始比较parent 节点。如果 child 大于 parent 节点,那么我必须交换它,否则我不必交换。然后我转到索引 2 并与 parent 进行比较,如果 children 大于 parent 节点,那么我必须交换它。然后索引 1 我必须与 children 进行比较并在需要时交换它。所以我创建了一个最大堆。 但我不明白为什么我必须用 A[5] 交换 A1 with A[6] then A1。最后我没有得到最大堆我得到了最小堆? Heapify 是什么意思?

非常感谢我感谢每一个答案!

我的一个练习是通过填充数组和树表示来说明堆排序的步骤

堆排序是一个两阶段过程。在第一阶段,将数组转入堆中,最大值位于顶部 A[1]。这是用红色圈出的第一个转换。在此阶段之后,堆位于从索引 1 到 6 的数组中,最大值位于 A[1] 中的索引 1 处。

在第二阶段,我们对值进行排序。这是一个多步骤过程,我们从堆中提取最大值并将其放入排序数组中。

堆在数组的左边,会向左收缩。排序后的数组在数组的右边,向左边增长。

在每一步中,我们将包含堆的最大值的堆 A[1] 的顶部与堆的最后一个值交换。排序后的数组然后向左增长了一个位置。由于已经放入A[1]的值不是最大的,我们必须恢复堆。这个操作称为 max-heapify。经过此过程后,A[1] 包含堆中的最大值,其大小已减少一个元素。

通过反复提取堆中剩余的最大值,我们可以对数组中的值进行排序。

二叉树的画法很乱。它的大小应该在每一步都缩小,因为堆的大小在缩小。

堆数据结构的实现有很多,但其中一个是在谈论特定的 implicit binary heap. Heap-sort is done in-place, so it uses this design. Binary heaps require a compete binary tree,因此它可以表示为从数组构建的隐式结构:对于每个 A[n]在 zero-based 数组中,

  • A[0]是根;如果 n != 0A[floor((n-1)/2)] 就是 parent;
  • 2n+1在数组范围内,则A[2n+1]为左child,否则为叶节点;
  • 如果2n+2在数组范围内,那么A[2n+2]就是对的child.

假设一个数组是,[10,14,19,21,23,31],使用上面的规则隐含地表示为同态,如,

这不遵循 max-heap 不变量,因此必须 heapify,可能使用 Floyd's heap construction,它使用 sift down 并在 O(n) 中运行。现在你有一个堆和一个没有长度的排序数组,([31,23,19,21,14,10],[]),(这都是隐式的,因为堆不占用额外的内存,它只是内存中的一个数组。)这个阶段堆的可视化,

我们弹出堆的最大元素,用sift up恢复堆的形状。现在堆小了一个,我们已经获取了最大元素并将其不移位地存储到我们的数组中,([23,21,19,10,14],[31])

重复,([21,14,19,10],[23,31])

([19,14,10],[21,23,31]),

([14,10],[19,21,23,31]),

([10],[14,19,21,23,31]),

堆大小为1,所以最终排序的数组为[10,14,19,21,23,31]。如果使用 min-heap 和相同的算法,则数组将以另一种方式排序。