堆中的siftUp和siftDown操作用于堆积数组

时间:2015-12-17 08:33:49

标签: arrays algorithm sorting heap

假设MAX-HEAPIFY操作。其中父元素值大于其子值。

  
      
  • siftDown交换一个太小的节点与其最大的子节点(从而将其向下移动),直到它至少与两个节点一样大   低于它。

  •   
  • siftUp与其父节点交换一个太大的节点(从而移动   它直到它不大于它上面的节点。 buildHeap   function接受一系列未排序的项目并将它们移动到它们之前   都满足堆属性。

  •   
  

buildHeap可能采用两种方法。一个是开始   在堆的顶部(数组的开头)并调用siftUp   每个物品。在每一步,先前筛选的项目(之前的项目   数组中的当前项)形成一个有效的堆,并筛选下一个   item up将它放入堆中的有效位置。筛选后   每个节点,所有项都满足堆属性。第二种方法   走向相反的方向:从阵列的末端开始并移动   向后朝前。在每次迭代中,您都会筛选一个项目   直到它在正确的位置。

让数组a有5个元素a [4,2,3,5,6]。

siftUp -

输入 - [4,2,3,5,6]

处理 -

从数组的开头应用siftUp操作。

siftUp(4) -
没有交换,因为它是根

 heapified Array-a[4]

siftUp(2) -

没有交换,因为父值(4)更多

heapified Array-a[4,2]

siftUp(3) -

没有交换,因为父值(4)更多

heapified Array-a[4,2,3]

siftUp(5) -

其父值为2,因此交换(5,2)。

          Array-a[4,5,3,2]

现在5的父值是4,所以再次交换(5,4)。

 heapified Array-a[5,4,3,2]

siftUp(6) -

首先在(6,4)之间,然后在(6,5)之间交换

 heapified Array-a[6,5,3,2,4]

输出一个[6,5,3,2,4]

siftDown -

输入 - [4,2,3,5,6]

处理 -

从数组的末尾开始,我们将逐个应用siftDown操作。

siftDown(6) -

它没有孩子所以没有交换。这同样适用于siftDown(5)和siftDown(3),因为他们没有任何孩子。所以他们不能再往下走了。

直到现在的数组 - [4,2,3,5,6]

siftDown(2) -

它与较大的子值交换。这里6是较大的一个。所以交换(2,6)。

现在阵列将是-a [4,6,3,5,2]

siftDown(4) -

4有两个孩子6和3.与较大的孩子交换。交换(4,6)完成。 现在数组将是[6,4,3,5,2]

再次4必须被交换,因为它有一个大于它自己的子,即5。所以交换(4,5)已经完成。

数组将是 - [6,5,3,4,2]

Heapified数组-a [6,5,3,4,2]

输出-A [6,5,3,4,2]

为什么在同一组元素上执行siftUp和siftDown操作时会得到两个不同的输出?或者,当siftUp和siftDown应用于同一组元素时,可能会有不同的堆。请澄清。 :)

2 个答案:

答案 0 :(得分:2)

是的,可以为同一组元素使用不同的堆。

两种方法都正确生成满足堆属性的堆:父元素值大于其子值

第一种方法:

    6
   / \
  5   3
 / \
2   4

第二种方法:

    6
   / \
  5   3
 / \
4   2

事实上,如果你手工绘制它,还有其他可能的堆,例如

    6
   / \
  4   5
 / \
2   3

但请注意,这两种方法虽然产生了正确的结果,但它们具有不同的复杂性。请参阅How can building a heap be O(n) time complexity?

答案 1 :(得分:1)

您描述的第一种方法(自上而下)不是从未排序数组构建堆的常规方法,可能是因为它需要O(n log n)时间!这是因为它意味着必须在底层执行筛选操作(底层大小为n / 2,其深度为log-n)。

正常的方法是对阵列进行自下而上的扫描,并对每个节点执行大幅下降。每个级别的时间将是级别中的节点数乘以高度(因为sift-down是recusrive并且可能一直交换到底层)。总时间为O(1 * n / 2 + 2 * n / 4 + 3 * n / 8 + ...)= O(n)*(1/2 + 2/4 + 3/8 + .. 。)= O(N)* 2 = O(n)中。

`
1/2 + 2/4 + 3/8 + 4/16 + ... =

1/2 + 1/4 + 1/8 + 1/16 + ... +
    + 1/4 + 1/8 + 1/16 + ... +
          + 1/8 + 1/16 + ... +
                + 1/16 + ... +
                       + ... =

1 +
1/2 +
1/4 +
1/8 +
... = 2

`