最小最大堆的Java实现?

最小最大堆的Java实现?,java,data-structures,minmax-heap,Java,Data Structures,Minmax Heap,你知道一个流行的库(Apache、Google等,collections)有一个可靠的Java实现来实现最小-最大堆,这是一个堆,它允许在O(1)中查看其最小值和最大值,并删除O(log n)中的元素。这个类怎么样?这是一部分;不幸的是,这可能是一个问题 看 但是,不实现decreaseKey或increaseKey。是否可以使用包含相同元素的两个实例来代替最大-最小堆?第一个实例将被传递一个比较器,该比较器将最大值置于头部,第二个实例将使用一个比较器,该比较器将最小值置于头部 缺点是必须在两种

你知道一个流行的库(Apache、Google等,collections)有一个可靠的Java实现来实现最小-最大堆,这是一个堆,它允许在
O(1)
中查看其最小值和最大值,并删除
O(log n)
中的元素。

这个类怎么样?这是一部分;不幸的是,这可能是一个问题


但是,不实现decreaseKey或increaseKey。

是否可以使用包含相同元素的两个实例来代替最大-最小堆?第一个实例将被传递一个比较器,该比较器将最大值置于头部,第二个实例将使用一个比较器,该比较器将最小值置于头部


缺点是必须在两种结构上执行添加、删除等操作,但它应该满足您的要求。

来自Guava:。

Java有很好的工具来实现最小和最大堆。我的建议是使用优先级队列数据结构来实现这些堆。要实现具有优先级队列的最大堆,请尝试以下操作:

import java.util.PriorityQueue;

public class MaxHeapWithPriorityQueue {

    public static void main(String args[]) {
    // create priority queue
    PriorityQueue<Integer> prq = new PriorityQueue<>((a,b)->b-a);

    // 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()+" ");
        }
    }

}
import java.util.PriorityQueue;
公共类MaxHeapWithPriorityQueue{
公共静态void main(字符串参数[]){
//创建优先级队列
PriorityQueue prq=新的PriorityQueue((a,b)->b-a);
//在队列中插入值
prq.添加(6);
prq.add(9);
prq.添加(5);
prq.add(64);
prq.添加(6);
//打印值
而(!prq.isEmpty()){
System.out.print(prq.poll()+);
}
}
}
要实现具有优先级队列的最小堆,请尝试以下操作:

import java.util.PriorityQueue;

public class MaxHeapWithPriorityQueue {

    public static void main(String args[]) {
    // create priority queue
    PriorityQueue<Integer> prq = new PriorityQueue<>((a,b)->b-a);

    // 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()+" ");
        }
    }

}
import java.util.PriorityQueue;
公共类MinHeapWithPriorityQueue{
公共静态void main(字符串参数[]){
//创建优先级队列
PriorityQueueprq=newpriorityqueue();
//在队列中插入值
prq.添加(6);
prq.add(9);
prq.添加(5);
prq.add(64);
prq.添加(6);
//打印值
而(!prq.isEmpty()){
System.out.print(prq.poll()+);
}
}
}
有关更多信息,请访问:

最小堆: PriorityQueue minHeap=new PriorityQueue()

最大堆数

PriorityQueue maxHeap=新的PriorityQueue(Comparator.reverseOrder())

我需要对重复值的支持。。。Set在这方面“有点”问题。-1 TreeSet在O(log n)中实现大多数操作-要求在O(1)中查看最小值和最大值。TreeSet也没有decreaseKey或increaseKey操作,这是堆的最终操作之一。如果需要支持重复值,可以使用ApacheCommons集合中的TreeBag()或Google集合中的TreeMultiset()。如果需要增加键或减少键,只需删除元素并重新添加即可。或者使用将键映射到计数的树形图。TreeSet实际上是通过引擎盖下的TreeMap实现的。+1。这是一个很好的答案,给出了在O(1)中窥视根并在O(log.n)中移除根的规定要求。但是请注意,PriorityQueue并没有实现所有堆操作(例如decreaseKey、increaseKey)。请注意,从队列头部移除的无参数
remove()
,是
O(log(n))
,而
remove(Object O)
,是
O(n)
。引用:被否决,因为删除将不再是O(logn)。从其中一个队列中删除最小值是O(logn),但删除另一个队列末尾的相同项是O(n)。@JimMischel这是我的想法,但后来我意识到我们仍然可以通过以下方式使双堆解决方案工作。当我们提取/peek max时,我们只从max堆中提取/peek max,反之亦然,从min堆中提取/peek max。当然,这会导致两个不一致的堆。我们跟踪最后提取的最大值和最后提取的最小值,这样当它们重合时,数据结构为空。如果我们不需要支持插入和键更改(在提取完成后),这将起作用,OP没有将其指定为要求。特别是因为最初的问题是关于google collections的,这就是现在的番石榴。唯一的一个小缺点是缺乏标准的
Deque
实施。它不符合Deque合同的要求,因此这是按预期进行的。您能澄清一下原因吗?我能看到的唯一困难是实现
Deque#removeFirstOccurrence()
removelastoccurrence()
由于minmax heapNo的不稳定性,问题是Deque必须保持在元素中的顺序。例如,
Deque
的文档指定,当它像队列一样使用时,会产生FIFO行为
MinMaxPriorityQueue
在技术上可以实现这些方法,但它不能满足契约要求。在MaxHeap类中作为PriorityQueue的参数使用更方便。您所说的更方便是什么意思?请你解释一下好吗?我认为reverseOrder方法比
(x,y)->y-x
更易于阅读和理解。在这一部分中,我使用了lambda表达式(Java 8)。然而,这是基于偏好。你的建议也很好。我很感激你的选择。在Lambda表达式中,通过减法比较的技巧很容易被打破,因为。建议进行简单比较:
(x,y)->x