我认为它是MergeSort,它是O(n log n)。
但是,以下输出不同意:
-1,0000000099000391,0000000099000427
1,0000000099000427,0000000099000346
5,0000000099000391,0000000099000346
1,0000000099000427,0000000099000345
5,0000000099000391,0000000099000345
1,0000000099000346,0000000099000345
我按序列号排序4个节点的节点列表,排序正在进行6次比较。 我很困惑,因为6> (4 log(4))。有人可以向我解释一下吗?
P.S. It is mergesort, but I still don't understand my results.
感谢大家的答案。谢谢汤姆纠正我的数学。
答案 0 :(得分:29)
O(n log n)并不意味着比较次数将等于或小于n log n,只是所花费的时间
答案 1 :(得分:24)
您排序了四个节点,因此您没有获得合并排序; sort切换到插入排序。
在Java中,Arrays.sort()方法使用合并排序或调整快速排序,具体取决于数据类型和实现效率当排序的数组元素少于七个时切换到插入排序。(维基百科,重点补充)
Arrays.sort由Collections类间接使用。
最近接受的错误报告表明,Sun的Java实现将来会使用Python的timsort:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6804124
(以上链接的timsort专着非常值得一读。)
答案 2 :(得分:3)
处理一定数量的数据n的算法A(n)在O(f(n))中,对于某些函数f,如果存在两个严格正常数C_inf和C_sup,则:
C_inf。 f(n)< ExpectedValue(OperationCount(A(n)))< C_sup。 F(N)
有两点需要注意:
实际常量C可以是任何东西,而 do 取决于操作的相对成本(取决于语言,VM,体系结构或操作的实际定义) 。例如,在某些平台上,+和*具有相同的成本,在某些平台上,后者的速度要慢一个数量级。
归因于“在O(f(n))中的数量”是预期的操作计数,基于您正在处理的数据的某些可能的任意模型。例如,如果您的数据几乎完全排序,合并排序算法将主要是O(n),而不是O(n.Log(n))。
答案 3 :(得分:2)
我写了一些你可能对Java排序算法感兴趣的内容,并采用了some performance measurements of Collections.sort()。一旦你达到一定大小的子列表,目前的算法是一个带有插入排序的 mergesort ( NB这个算法很可能在Java 7中发生变化)。
你应该把Big O表示法作为算法如何整体扩展的指示;对于特定的排序,精确的时间将偏离此计算预测的时间(正如您在我的图表中看到的,组合的两种排序算法各自具有不同的性能特征,因此排序的总时间是有点复杂)。
那就是说,作为一个粗略的指南,每当你将元素数量增加一倍时,如果你将预期时间乘以2.2,你就不会太远了。 (尽管如此,对于一些非常小的元素列表来说,真的没有多大意义。)