通过min-sheaps进行堆垛和分拣

时间:2011-10-30 17:41:16

标签: java algorithm heapsort

我知道如何使用heapsort和max-heap属性对数组进行排序 但我想不出如何使用 min -heap属性对其进行排序。

我可以使用临时中间数组使用min-heap对其进行排序,例如

public static int[] heapSort2(int[] array){
     buildMinHeap(array);
     int [] temp = new int[array.length];
     for(int i = 0; i < array.length; i++ ){
      temp[i] = extractMin(array);
      } 
   return temp;//returns array input sorted
}

但是如果不使用temp,我无法想办法。是可能的,还是只有优先级队列的最小堆?

1 个答案:

答案 0 :(得分:2)

使用min-heap进行就地排序与使用max-heap进行排序是对称的。

假设您按升序排序,并且您有一个最大堆数组,并且根始终位于第一个元素(索引1)中,并且您通过将根移动到的位置执行一个排序步骤最后一个叶子(这是尚未排序的最右边的元素),使这个叶子成为新的根并将其沉入堆中。

然后通过使用最小元素(索引N)中的根始终,使用min-heap数组按升序排序,然后通过将根移出到该位置来执行一个排序步骤最后一个叶子(它是尚未排序的最左边的元素),使这个叶子成为新的根并将其沉入堆中。

在这样的堆中获取父,左和右孩子的索引的等式是不同的。在前一种情况下,假设指数1> N,则等式为:

parent(i) = floor(i / 2)
leftchild(i) = 2 * i
rightchild(i) = 2 * i + 1

在后者中,反转的小堆情况,通过反转上述输入和输出的指数得到方程:

parent(i) = N + 1 - floor((N + 1 - i) / 2)
leftchild(i) = N + 1 - (2 * (N + 1 - i))
rightchild(i) = N + 1 - (2 * (N + 1 - i) + 1)

你可以看到后者的方程式与前者相比看起来很丑陋(但可能会简化它们)。因此,在按升序排序时,最好只使用最大堆,而不是最小堆。 仅当您希望按降序排序时使用最小堆 - 与按升序排序时使用max-heap的方向相同(在第一个元素上为root)。