Java Collections.sort(节点)使用什么排序?

Java Collections.sort(节点)使用什么排序?,java,collections,sorting,time-complexity,mergesort,Java,Collections,Sorting,Time Complexity,Mergesort,我认为是MergeSort,它是O(n logn) 但是,以下输出不一致: -1,0000000099000391,0000000099000427 1,0000000099000427,0000000099000346 5,0000000099000391,0000000099000346 1,0000000099000427,0000000099000345 5,0000000099000391,0000000099000345 1,0000000099000346,000000009900

我认为是MergeSort,它是O(n logn)

但是,以下输出不一致:

-1,0000000099000391,0000000099000427
1,0000000099000427,0000000099000346
5,0000000099000391,0000000099000346
1,0000000099000427,0000000099000345
5,0000000099000391,0000000099000345
1,0000000099000346,0000000099000345
我正在按序号对一个包含4个节点的节点列表进行排序,该排序将进行6次比较。 我很困惑,因为6>(4日志(4))。有人能给我解释一下吗


谢谢大家的回答。谢谢汤姆纠正了我的数学错误。

O(n logn)并不意味着比较的次数等于或小于n logn,只意味着所花费的时间将与n logn成比例地缩放。尝试使用8个节点、16个节点或32个节点进行测试,并检查计时。

您对4个节点进行了排序,因此没有进行合并排序;排序切换为插入排序

在Java中,Arrays.sort()方法使用合并排序或优化的快速排序,具体取决于数据类型和实现效率当排序的数组元素少于七个时,切换到插入排序。(Wikipedia,emphasis添加)

集合类间接使用Arrays.sort

一份最近被接受的bug报告指出,Java的Sun实现将来将使用Python:

(上面链接的timsort专著非常值得一读。)

对于某些函数f,如果存在两个严格正常数C_inf和C_sup,则处理大量数据n的算法A(n)为O(f(n)):

C_inf。f(n) 有两点需要注意:

  • 实际常数C可以是任何东西,并且取决于操作的相对成本(取决于语言、VM、体系结构或操作的实际定义)。例如,在某些平台上,+和*的成本相同,而在另一些平台上,+和*的成本要低一个数量级

  • “in O(f(n))”是一个预期的操作计数,基于您正在处理的数据的一些可能任意的模型。例如,如果您的数据几乎被完全排序,那么合并排序算法将主要是O(n),而不是O(n.Log(n))


我已经写了一些您可能感兴趣的关于Java排序算法的内容,并采取了一些措施。目前的算法是一种带有插入排序的合并排序算法,一旦你得到了一定大小的子列表(N.B.这种算法在Java 7中很可能会改变)

你真的应该把大O符号作为算法整体扩展的指标;对于特定的排序,精确时间将偏离此计算预测的时间(正如您在我的图表上看到的,组合的两种排序算法各自具有不同的性能特征,因此排序的总时间稍微复杂一些)


也就是说,作为一个粗略的指导,每次你把元素的数量增加一倍,如果你把预期的时间乘以2.2,你就不会太远了。(不过,对于包含几个元素的非常小的列表来说,这样做没有多大意义。)

啊,我明白了。我假设这是比较的次数。我的错误。谢谢这是一个非常小的比较数量,您可以轻松地将其乘以1000以获得更好的结果。是的,但他的示例最初是4:)(JDK7中的Collections.sort应该对部分排序的数据进行一些比较。Josh Bloch移植了Python的Tim sort(合并排序的一个版本)。)如果它是log base 2(表示法??),则为4 log[2]4=4 log[2](2^2)=4.2 log[2]2=4.2.1=8。(如果我没记错的话)但是,是的,那里有一个常数。所以我猜JDK7默认使用timsort?上周四的OpenJDK论坛:核心库圆桌会议也提到了这一点。[MP3!]快速排序胜过合并排序。Java使用quicksort作为排序算法。quicksort上的常量非常小,因为它已经就位。Timsort是合并排序和插入排序的混合,它在合并阶段使用插入排序,因此不会获得太多好处。与快速排序相比,该常数仍然较高。对于任意大小的n位整数,+通常为O(n)和*IIRC O(n log n)。只需使用大整数和相对较少的(大O)运算,就可以对算法做一些“有趣”的事情。快速排序是一个典型的算法示例,它主要是O(n log n),但可以是O(n^2)(例如,以第一个元素为轴心的排序输入)。是的。。。对于所有这些复杂度评估任务,魔鬼就在模型中。对于任何用途,您通常还必须考虑最坏情况的复杂性,而不仅仅是预期成本。发现最坏的情况通常是一个好办法。。。