【问题标题】:sort while inserting or copy and sort插入时排序或复制和排序
【发布时间】:2014-06-10 09:04:35
【问题描述】:

我有一个迭代器,它给了我 n 个元素。目前我将它们一一复制到一个 ArrayList 中,然后在该列表上调用 Collections.Sort() 以获得排序后的 ArrayList。这需要 nlog(n)+n 次操作。有没有更快的方法,即我可以在一定程度上使用插入操作吗?

迭代器不进行任何排序,元素几乎随机出现。

【问题讨论】:

  • 你的元素是独一无二的吗?
  • 尝试基数排序,它是o(n+k)
  • 如果您的列表应该是有序列表,为什么在插入时处理它?
  • @ChiefTwoPencils 请参阅下面我对肯特回答的评论。插入到 ArrayList 中,同时保持数组中所有其他元素的顺序,并且 Array 中的运行时间为 O(n)。

标签: java arrays sorting arraylist insert


【解决方案1】:

如果你只有那个迭代器,我看不到更快的解决方案。注意nlogn+n 也是O(nlogn)

如果你想“在插入时排序”,你需要在每次插入时进行二进制搜索,它也是O(nlogn)。我认为它不会比你拥有的快得多。

TreeSet 可以把你从二分查找的实现中解救出来,但基本上是一样的逻辑。

【讨论】:

  • @Kent 感谢您的回答。我试图不在朗道符号中考虑这个问题,因为 nlog(n) 前面的常数因子越小,我的应用程序就越好。因此,第一次使用二进制搜索执行插入排序看起来很有希望,但是由于我正在处理 ArrayList,对于每个插入的元素,我可能必须移动一些 O(n) 元素,这将使其与我原来的做法。所以我现在会坚持下去。再次感谢您与我一起思考。
【解决方案2】:

由于迭代器既不是集合也不是容器,因此不可能像您已经注意到的那样直接在迭代器中进行排序。在这种情况下,您使用的方法似乎是最好的解决方案。

【讨论】:

    【解决方案3】:

    如果您的元素是唯一的,您可以将它们放入 TreeSet,然后将它们从 TreeSet 复制到 ArrayList 中。不过,这实际上可能不会比您已经在做的更快。

    除此之外,您不太可能比现有的更进一步优化。编写自己的插入排序几乎肯定会比仅使用高度优化的 Java 排序例程慢。

    不过,您可以考虑查看 Java 8 中的新 Java Streams API。这将允许您通过将迭代器作为流打开、对其进行排序、然后将其整理到最终集合中来做到这一点。

    http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

    【讨论】:

      【解决方案4】:

      如果您的数组中有对象而不是原始数据类型(例如 int、double),则必须考虑对象复制的成本。在这种情况下,对数组索引进行排序可能是更好的方法。仅当需要同时处理排序和插入时,使用搜索数据结构 map/set 比较好。

      【讨论】:

        猜你喜欢
        • 2011-09-01
        • 1970-01-01
        • 2015-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-30
        • 2021-05-30
        • 1970-01-01
        相关资源
        最近更新 更多