Java 优先队列堆化
Java Priority Queue heapify
一般来说,如果我理解正确的话,“heapifying;o(n)”给定列表与添加每个单独元素之间的运行时间是不同的; o(lgn)。 java 是否遵循此行为?如果不是以下问题可能无效。
下面的示例似乎创建了一个“最小堆”。
List<Integer> myList = List.of(4,3,10,1);
PriorityQueue<Integer> queue = new PriorityQueue<>(myList);
但是,假设我想构建一个“最大堆”,但是构造函数不允许我同时传入集合和比较器。在这种情况下,构建最大堆的唯一方法是通过创建一个实现可比性的包装器 class?
class Wrapper implements Comparable<Wrapper> {
...
@Override
int compareTo(Wrapper o) {// define rule here...}
}
List<Integer> val = List.of(5,3,2,10);
List<Wrapper> wrappedVal = val.stream().map(Wrapper::new).collect(Collectors.toList());
PriorityQueue<Wrapper> queue = new PriorityQueue<>(wrappedVal);
注意:我知道可以使用比较器创建优先级队列,然后重复调用 add。
However, let say if I want to build a "max heap", but the constructor does not let me pass in a collection and comparator together. In this case, is the only to build max heap is via creating a wrapper class that implements comparable?
是的。这个class没有提供可以同时传入一个collection
和一个comparator
的构造函数。它将使用集合元素的compareTo
方法,所以像你一样,你需要一个Wrapper
(但这似乎有点不必要?)。
repeatedly call add.
您可以使用 PriorityQueue#addAll()
.
来自 java 文档:
The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at QUEUE CONSTRUCTION TIME, depending on which constructor is used
https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html
所以你必须在构建队列时提供排序策略。假设您正在尝试拥有最大堆(以相反的方式排序),那么队列构造将如下所示:-
Queue<Integer> queue = new PriorityQueue<>(new YourCustomComparator())
或者,如果您只是处理整数,您可以利用自定义整数:
Queue<Integer> queue = new PriorityQueue<>(Collections.reverseOrder());
这一步只是创建队列。现在如何添加元素?这里有多种可用的方法签名。假设您有可用的列表,那么您可以简单地将它们传递给 addAll 方法。
像这样:
queue.addAll(List.of(5, 3, 2, 10));
一般来说,如果我理解正确的话,“heapifying;o(n)”给定列表与添加每个单独元素之间的运行时间是不同的; o(lgn)。 java 是否遵循此行为?如果不是以下问题可能无效。
下面的示例似乎创建了一个“最小堆”。
List<Integer> myList = List.of(4,3,10,1);
PriorityQueue<Integer> queue = new PriorityQueue<>(myList);
但是,假设我想构建一个“最大堆”,但是构造函数不允许我同时传入集合和比较器。在这种情况下,构建最大堆的唯一方法是通过创建一个实现可比性的包装器 class?
class Wrapper implements Comparable<Wrapper> {
...
@Override
int compareTo(Wrapper o) {// define rule here...}
}
List<Integer> val = List.of(5,3,2,10);
List<Wrapper> wrappedVal = val.stream().map(Wrapper::new).collect(Collectors.toList());
PriorityQueue<Wrapper> queue = new PriorityQueue<>(wrappedVal);
注意:我知道可以使用比较器创建优先级队列,然后重复调用 add。
However, let say if I want to build a "max heap", but the constructor does not let me pass in a collection and comparator together. In this case, is the only to build max heap is via creating a wrapper class that implements comparable?
是的。这个class没有提供可以同时传入一个collection
和一个comparator
的构造函数。它将使用集合元素的compareTo
方法,所以像你一样,你需要一个Wrapper
(但这似乎有点不必要?)。
repeatedly call add.
您可以使用 PriorityQueue#addAll()
.
来自 java 文档:
The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at QUEUE CONSTRUCTION TIME, depending on which constructor is used https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html
所以你必须在构建队列时提供排序策略。假设您正在尝试拥有最大堆(以相反的方式排序),那么队列构造将如下所示:-
Queue<Integer> queue = new PriorityQueue<>(new YourCustomComparator())
或者,如果您只是处理整数,您可以利用自定义整数:
Queue<Integer> queue = new PriorityQueue<>(Collections.reverseOrder());
这一步只是创建队列。现在如何添加元素?这里有多种可用的方法签名。假设您有可用的列表,那么您可以简单地将它们传递给 addAll 方法。
像这样:
queue.addAll(List.of(5, 3, 2, 10));