为什么siftDown比heapify中的siftUp好?

时间:2012-10-23 07:05:25

标签: algorithm complexity-theory

要构建MAX堆树,我们可以siftDownsiftUp,通过筛选我们从根开始并将其与其两个子节点进行比较,然后我们将其替换为更大的元素两个孩子,如果两个孩子都小,那么我们停下来,否则我们继续筛选那个元素,直到我们到达一个叶子节点(当然,再一次,直到那个元素比它的两个孩子都大)。

现在我们只需要执行n/2次,因为叶子的数量是n/2,当我们完成堆积最后一个元素之前,叶子将满足堆属性最后(在叶子之前) - 所以我们将留下n/2个元素来堆积。

现在,如果我们使用siftUp,我们将从叶子开始,最终我们需要堆积所有n个元素。

我的问题是:当我们使用siftDown时,我们不是基本上进行两次比较(将元素与其两个子元素进行比较),而不是在使用siftUp时只进行一次比较,因为我们只将该元素与其父元素进行比较?如果是的话,这是不是意味着我们将复杂性加倍,并且真正以与筛选相同的复杂性结束?

1 个答案:

答案 0 :(得分:22)

实际上,重复调用siftDown来构建堆的复杂性为O(n),而重复调用siftUp来构建堆的复杂性为O(nlogn)

这是因为当您使用siftDown时,每次调用所需的时间会随着节点的深度减少,因为这些节点更接近叶子。当您使用siftUp时,交换次数会随着节点的深度增加,因为如果您处于全深度,则可能必须一直交换到根。随着节点数量随着树的深度呈指数增长,使用siftUp会提供更昂贵的算法。

此外,如果您使用Max-heap进行某种排序,其中弹出堆的max元素然后重新定义它,则使用siftDown更容易实现。您可以通过弹出max元素,将最后一个元素放在根节点(因为弹出它而为空)然后将其一直向下筛回到正确的位置,在O(logn)时间内重新定义。