【问题标题】:Java Sort functionsJava 排序函数
【发布时间】:2015-04-22 00:25:30
【问题描述】:

在 java 中,collections.sort 使用合并排序算法而不是快速排序。但是 Arrays.sort 使用快速排序。 (我不确定上述事实,但我在互联网上找到了这个,比如在CodeRanch 等网站上,如果他们不使用该算法,请告诉我)

现在我知道两种算法的平均复杂度是相同的。唯一的事实是快速排序最糟糕的是 O(n^2) 但这并不常见。 而且我们不关心当今世界的空间,所以归并排序不是就地算法并不重要。 但是我们关心稳定性,所以为什么我们对 array.sort 使用快速排序,因为它不是一个稳定的算法。是不是因为它只关心整数,但我不认为这是一个很好的理由。

【问题讨论】:

  • 我以为他们都使用了 TimSort。我需要检查源代码。
  • 哦,你确定我是在网上找到的。
  • @ArjunChaudhary “我在互联网上发现的”非常没有帮助。你在哪里找到的?
  • @dimo414 这里有东西给coderanch.com/t/520171/java/java/…

标签: java algorithm sorting collections


【解决方案1】:

Arrays.sort 仅对原始数组使用双轴快速排序算法,其中稳定和不稳定排序算法之间没有区别。这通常被认为是稍微快一点,但它并不稳定,所以它只用于稳定性无关紧要的情况。

Arrays.sort 用于对象数组,Collections.sort 使用 Timsort,这是一种合并排序变体,可进行稳定排序。

【讨论】:

    【解决方案2】:

    您的前提可以通过查看相关的Javadocs 甚至source code 轻松验证。首先,注意Collections.sort(List<T>) 只是委托给Arrays.sort(Object[]) (source):

    public static <T extends Comparable<? super T>> void sort(List<T> list) {
        Object[] a = list.toArray();
        Arrays.sort(a);
        ListIterator<T> i = list.listIterator();
        for (int j=0; j<a.length; j++) {
            i.next();
            i.set((T)a[j]);
        }
    }
    

    所以这两种方法将具有相同的行为和运行时。如文档中所述,实现是TimSort,一种合并排序和插入排序的混合体。保证稳定。因此,无论是数组还是集合,对对象进行排序都是一样的。

    您链接到的文章指的是对 原始 数组进行排序。关于原始数组需要做的假设更少,特别是相等的原始数组,根据定义,是无法区分的。这意味着不需要确保稳定的排序。你会注意到原始排序方法的文档,比如Arrays.sort(int[]),没有提到这些排序方法的稳定性,因为这样的细节是没有意义的。仅当对可以相等但不相同的数据进行排序时,稳定性才重要。

    【讨论】:

      【解决方案3】:

      Arrays.sort 并没有真正使用常见的快速排序实现,javadoc 指定:

      排序算法是 Vladimir 的 Dual-Pivot Quicksort 雅罗斯拉夫斯基、乔恩·本特利和约书亚·布洛赫。该算法提供 在导致其他快速排序的许多数据集上的 O(n log(n)) 性能 降级到二次性能,并且通常比 传统(单轴)快速排序实现。

      看看位于DualPivotQuicksort的排序算法;正如您在 cmets 中看到的,根据给定的数组使用不同的排序算法。

      至于Collections 排序方法,它在接收到的实现上调用sort,该实现(在我验证的情况下)委托给Arrays.sort

      【讨论】:

        【解决方案4】:

        Arrays.sort 会比 Collections.sort 稍微快一些,因为 Collections.sort 在内部调用 Arrays.sort。 在处理基元时,稳定性无关紧要,因为可以重新排列相同值的基元而不会产生副作用。并且 Arrays.sort 提供了额外的性能优势。因此,对于原始数组,Arrays.sort 将是首选。

        【讨论】:

        • 这不能回答问题。
        • 是的,实际上是关于他们使用哪种算法以及为什么?
        猜你喜欢
        • 2011-07-23
        • 2015-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-29
        • 2023-04-02
        相关资源
        最近更新 更多