从大量输入中获取排序列表(有限长度)的最佳方法是什么?

时间:2014-10-09 05:03:40

标签: java algorithm sorting

所以,让我们说我有1亿Comparable作为流媒体输入,我想输出那个输入的前100个(按顺序 - 这是微不足道的我想你,如果你可以找到前100名)。我假设某种插入排序最好,但实现这一目标的最佳方法是什么(如果它是最好的方式)?

约束条件是你肯定会一次看到一个对象(我肯定不能将整个集合放入内存中)。

我在考虑两种可能的解决方案:

1)一个简单的链表。因此,当前100个对象进入时,它们将被排序(花费O(n)时间 - 但是n = 100)。然后当每个连续的对象进入时,它将被正确插入(再次O(n),n = 100,时间),如果插入,它将踢出尾部(否则链接列表将保持不变,如果它'超过最大值)。

2)使用堆。我想我可以保留一个堆,插入堆中,然后丢弃根节点(堆顶部),如果堆的大小高于我的最大元素数(在我的情况下为100)。这应该意味着O(lg(n))运行时,对吧?由于元素的插入和根的删除都是O(lg(n)),对吧?

Java中的堆有没有好的库?我真的不想编写自己的堆结构。

P.S。

如果您想知道为什么我这样做,那就是幻想足球的目的。我有一个程序,可以在salaray帽的约束下找到一组玩家的最大投射点(它是一个强力算法)。事实上,完全是另一个问题,即如何解决背包问题,其中必须具有一定数量的不同类型的项目(即1 QB,3 WR,2 RB,1 TE,1 K和1防御。)

所以我有一大组(1,234)的球队给出了最低的预计积分数,但现在我试图找到拥有各种不同球员的球队。我认为一组三支球队是合理的解决(通过暴力):1,234选择3 = 312,419,184(根据我的计算,将花费大约一个半小时来处理)。我计算了一组球队'方差是玩家在每个团队中出现的次数(因此值越低,团队组别越大)。

1 个答案:

答案 0 :(得分:2)

如果你要做的只是添加,你可以使用它。

public static <T> SortedSet<T> topValues(final int n, final Comparator<T> comparator) {
    return new TreeSet<T>(comparator) {
        @Override
        public boolean add(T t) {
            // if less than N in size, just try to add it.
            if (super.size() < n)
                return super.add(t);

            T first = super.first();
            // if smaller than the first, discard it.
            if (comparator.compare(t, first) <= 0)
                return false;
            // otherwise try to add it.
            super.remove(first);
            super.add(t);
            return true;
        }
    };
}

或者该类型已经是可比较的

public static <T extends Comparable<T>> SortedSet<T> topValues(final int n) {
    return new TreeSet<T>() {
        @Override
        public boolean add(T t) {
            // if less than N in size, just try to add it.
            if (super.size() < n)
                return super.add(t);

            T first = super.first();
            // if smaller than the first, discard it.
            if (t.compareTo(first) <= 0)
                return false;
            // otherwise try to add it.
            super.remove(first);
            super.add(t);
            return true;
        }
    };
}

只需将所有值添加到此集合中,它只会有n个值,每次丢弃最小值。