您是否知道一个受欢迎的库(如Apache、Google和collections)具有可靠的Java实现的min-max堆,即堆可以在O(1)
时间内查看其最小值和最大值,并且可以在O(log n)
时间内删除元素?
您是否知道一个受欢迎的库(如Apache、Google和collections)具有可靠的Java实现的min-max堆,即堆可以在O(1)
时间内查看其最小值和最大值,并且可以在O(log n)
时间内删除元素?
Java有很好的工具来实现最小堆和最大堆。我的建议是使用优先队列数据结构来实现这些堆。要使用优先队列实现最大堆,请尝试以下操作:
import java.util.PriorityQueue;
public class MaxHeapWithPriorityQueue {
public static void main(String args[]) {
// create priority queue
PriorityQueue<Integer> prq = new PriorityQueue<>(Collections.reverseOrder());
// insert values in the queue
prq.add(6);
prq.add(9);
prq.add(5);
prq.add(64);
prq.add(6);
//print values
while (!prq.isEmpty()) {
System.out.print(prq.poll()+" ");
}
}
}
要使用优先队列实现最小堆,请尝试以下方法:
import java.util.PriorityQueue;
public class MinHeapWithPriorityQueue {
public static void main(String args[]) {
// create priority queue
PriorityQueue< Integer > prq = new PriorityQueue <> ();
// insert values in the queue
prq.add(6);
prq.add(9);
prq.add(5);
prq.add(64);
prq.add(6);
//print values
while (!prq.isEmpty()) {
System.out.print(prq.poll()+" ");
}
}
}
更多信息请访问:
(x, y) -> x < y ? -1 : x == y ? 0 : 1
。 - Ruifeng Ma不一定非要使用最大-最小堆,您是否可以使用两个实例的java.util.PriorityQueue来包含相同的元素?第一个实例将传递一个比较器,该比较器将把最大值放在头部,而第二个实例将使用将最小值放在头部的比较器。
缺点是添加、删除等操作必须在两个结构上执行,但它应该能够满足您的要求。
remove()
方法会从队列头部删除元素,其时间复杂度为 O(log(n))
,而有参数的 remove(Object o)
方法时间复杂度为 O(n)
。参考链接:http://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html - erwaman最小堆: PriorityQueue minHeap = new PriorityQueue<>();
最大堆: PriorityQueue maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
你可以简单地传递要用于比较元素的比较器。即使你想根据某些属性对对象进行排序,这也会变得很有用。看下面的示例:
Min Heap :
PriorityQueue<Integer> pq = new PriorityQueue<>((a,b) -> a - b);
Max Heap :
PriorityQueue<Integer> pq = new PriorityQueue<>((a,b) -> b - a);
Min Heap for Objects
PriorityQueue<MyObject> pq = new PriorityQueue<>((obj1, obj2) -> obj1.getId() - obj2.getId());
Max Heap for Objects
PriorityQueue<MyObject> pq = new PriorityQueue<>((obj1, obj2) -> obj2.getId() - obj1.getId());
[key,stamp]
对来实现重复值和稳定排序,因此首先对键进行比较,然后对戳记进行比较。但是,TreeSet
不能替代最大-最小堆双端队列。 - Alex Salauyou
Deque
实现。 - Alex SalauyouDeque#removeFirstOccurrence()
和removeLastOccurence()
,因为最小-最大堆的不稳定性。 - Alex SalauyouDeque
的文档规定,当它像队列一样使用时,会产生FIFO行为。MinMaxPriorityQueue
理论上可以实现这些方法,但无法满足契约。 - Louis WassermanMinMaxPriorityQueue
源代码后,我意识到它并没有实现一个“真正的” _min-max堆_(很少有人知道),而是仅仅使用了两个堆,一个最小堆和一个最大堆,将它们组合在一起来实现一个双端优先队列。 - nbro