我有一个未分类的对象集合[可比较],是否有可能获得列表集合的子列表而无需调用sort?
我正在考虑使用有限容量执行SortedList的可能性,但这看起来不是正确的选项。
我可以很容易地写出这个,但我想知道是否还有另一种方法。
我无法修改现有集合的结构。
答案 0 :(得分:5)
由于您不想调用sort()
,因此您似乎正在尝试避免 O(n log(n))运行时成本。 实际上是在 O(n)时间内完成此操作的方法 - 您可以使用selection algorithm。
在Guava库中有一些方法可以做到这一点(谷歌的核心Java库);查看Ordering
并查看:
public <E extends T> List<E> Ordering.leastOf(Iterable iterable, int k)
public <E extends T> List<E> Ordering.greatestOf(Iterable iterable, int k)
这些是quickselect的实现,因为它们是一般编写的,您可以在Set
上调用它们并获取k
最小的事物列表。如果您不想使用整个Guava库,那么文档链接到源代码,我认为将方法移植到项目中应该很简单。
如果你不想偏离标准库太远,你总是可以使用像TreeSet
这样的有序集合,虽然这可以获得对数插入/删除时间而不是漂亮的 O( 1)基于散列的Set
的性能,最终最终成为 O(n log(n))。其他人提到使用堆。这也将为您提供 O(n log(n))运行时间,除非您使用某些fancier heap variants。如果你正在寻找其中一个,那就有一个fibonacci heap implementation in GraphMaker。
其中哪些有意义取决于您的项目,但我认为这涵盖了大部分选项。
答案 1 :(得分:1)
我可能会创建一个有序集。将未分类集合中的前N个项目插入到已排序集合中。那么对于未分类的集合的剩余部分:
答案 2 :(得分:1)
是的,如果项目小于最大堆中的最大值(通过检查get()
“,则可以将它们全部放入固定大小为N的max heap data structure中偷看“方法”。一旦你这样做了,根据定义,它们将是最小的N.最佳实现将使用O(M)+lg(N)
或O(M)
(其中M是集合的大小)性能执行,这在理论上是最快的。这是一些伪代码:
MaxHeap maxHeap = new MaxHeap(N);
for (Item x : mySetOfItems) {
if (x < maxHeap.get()) {
maxHeap.add(x);
}
}
Apache Commons Collections class PriorityBuffer似乎是他们的旗舰二进制堆数据结构,尝试使用那个。
答案 3 :(得分:0)