如何创建最小堆?

时间:2017-10-07 21:51:41

标签: java heap

在代码中给出了一串字符串,我们在流中返回k个最长的字符串。我的问题是比较器是如何工作的?我知道我们使用匿名函数覆盖compare方法来比较两个字符串的长度,但这个比较如何创建一个最小堆?

public static List<String> topK(int k, Iterator<String> iter) {
PriorityQueue<String> minHeap = new PriorityQueue<>(k, new Comparator<String>() {
   public int compare(String s1, String s2) {
     return Integer.compare(s1.length(), s2.length());  
   }
});
while (iter.hasNext()) {
  minHeap.add(iter.next());
  if (minHeap.size() > k) {
    // Remove the shortest string. Note that the comparison function above
    // will order the strings by length.
    minHeap.poll();
  }
}
return new ArrayList<>(minHeap);
}

2 个答案:

答案 0 :(得分:1)

来自Javadoc of PriorityQueue

  

此队列的头部是指定排序的最小元素。

PriorityQueue.poll()

  

检索并删除此队列的头部,如果此队列为空,则返回null。

比较器通过增加长度来对元素进行排序,因此队列的头部是长度最小的队列。因此,当您调用poll()时,将从队列中删除最短的字符串。

如果弹出以便只保留队列中的大多数k个项目,那么这些项目将是迄今为止从迭代器中获取的k个最长项目。一旦迭代器耗尽,那些将是(最多)k个最长的项目。

答案 1 :(得分:0)

试着用简单的词汇总结

二进制堆是二进制队列后面的一种特殊类型的树数据结构。在堆中,每个节点及其子节点都遵循一些常见模式。例如,在最小堆中,所有子节点必须大于父节点。因此,根节点保持最小的数字。

在堆中,当堆中有任何更改(插入,删除,更新)时,堆以某种方式重组,以便维护公共原则(例如,在上面的情况下,父级总是更小)比它的孩子)。因此,当在堆上执行某些操作时,将调用heapify操作。因此,对于最小堆,将调用min-heapify来维持原则。因此,在min-heapify操作中,父项将与递归的子节点进行比较,以检查哪一个具有较低的值,如果子项具有较低的值,则将与父项交换。

现在,在您的情况下,您只是实现了heapify操作的这种比较方法。因此,对于最大堆,您将执行相反的操作(将更高的值设置为父级)。此外,您可以通过满足自己的需要来实现自定义比较方法。

要了解更多详细信息,您可以使用二进制堆进行搜索,并且可以找到大量优质资源。