【问题标题】:Is it faster to merge and then sort, or sort and then merge?是先合并再排序,还是先排序再合并?
【发布时间】:2013-04-02 05:15:25
【问题描述】:

我有 2 个未排序的数组。单独排序然后合并它们会更快吗?还是先连接数组然后对组合的巨大数组进行排序会更快?

【问题讨论】:

  • 似乎第二种方法更快,因为连接比合并更快。
  • 我更喜欢分而治之。快速排序和合并排序从中受益。
  • @Egor 排序的线性度低于串联和合并(除非我们谈论的是基数排序)。
  • @AlexeyFrunze - 你能详细说明一下吗?分而治之究竟如何?您的意思是使用快速排序对两个数组进行排序,然后使用归并排序将它们放在一起吗?

标签: java algorithm merge sorting


【解决方案1】:

假设在O(1) 中完成连接,合并需要O(n) 和排序O(n log n),您可以选择:

  • 排序和合并:O(n log n) + O(n) = O(n log n)
  • 连接和排序:O(1) + O((2n) log (2n)) = O(n log n)

因此,渐近两个选项是等价的。

当然,如果您使用 MergeSort,那么整个讨论都是没有实际意义的。

【讨论】:

  • 我认为 Java 中的连接不会是 O(1)
  • @assylias:很可能是这样。但是,只要连接不超过 O(n log n) 操作,该参数仍然有效。
【解决方案2】:

显然,big-O 在这个问题上并没有真正说明什么。假设您使用的算法是快速排序。 It has a average running time of:

所以现在,如果排序然后合并我们得到:

f1 = 1.39n * log(n) * 2 + 2n

合并然后排序:

f2 = n + 1.39 * 2n * log(2n)

区别是

f2 - f1 = -n + 2.78n > 0

一般情况下,如果排序算法具有复杂性

C = k * nlog(n)

那么由于 k 通常应该大于 1,并且不太可能接近 0.5,如果您假设合并成本最多为 2n,则排序然后合并会更快。

【讨论】:

  • 我觉得这样分析一个算法的运行时间意义不大。使用 big-O 表示法忽略的实际常量表明它更准确,但您仍然只计算选定操作(比较次数、复制次数)并忽略许多其他操作(方法调用、缓存效果等)。 IMO,如果您想执行比 big-O 更接近现实的分析,您还应该考虑所有系统/语言/实现特定的常量,并改用分析器。
  • @blubb 你绝对是对的;我忘了输入我的答案,即这只比较随机输入时的平均比较次数。上面的分析肯定应该扩展,并定义计算模型。稍后我将尝试编辑答案,使其更加真实,而不是只是一个高雅的废话。
【解决方案3】:

我认为这取决于排序算法和数据的大小。

但一个疯狂的猜测是合并然后排序整个批次是更可取的。因为这种情况下的合并只是追加。

而在其他情况下,您需要应用排序合并。

【讨论】:

  • 虽然您的答案可能更易于编码,但问题所要求的并不是更快。
  • 我认为在具体代码运行之前没有明确的答案。
【解决方案4】:

当保证第二个数组中的所有条目都大于第一个数组中的所有条目时,您可以在对每个数组进行排序后连接数组。每种排序算法都有比线性更差的复杂性,所以当你可以将排序任务分解为可以单独排序的子集时,你应该这样做。

但是当合并数组后需要再次对条目进行排序时,事先对每个数组进行排序不太可能使这更快。

如果您想准确了解它,请创建大量测试数据并自己衡量性能。

【讨论】:

    【解决方案5】:

    这取决于您使用的技术。

    先排序然后合并会在现代多处理器架构上为您提供更好的结果,您可以在并行线程中的两个数组上运行排序算法大约O(nlogn)(但常数要小得多),然后将它们合并到@ 987654322@时间。

    【讨论】:

      猜你喜欢
      • 2012-12-02
      • 2013-11-13
      • 1970-01-01
      • 1970-01-01
      • 2014-01-08
      • 2022-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多