假设我有一个班级: `
public class Interval {
int start;
int end;
Interval() { start = 0; end = 0; }
Interval(int s, int e) { start = s; end = e; }
}
`
我想用Collections.sort()对这些间隔列表进行排序:
Collections.sort(intervals, new Comparator<Interval>(){
@Override
public int compare(Interval o1, Interval o2) {
if (o1.start == o2.start) {
return o1.end - o2.end;
}
else {
return o1.start - o2.start;
}
}
});
我知道使用内置排序函数对数组进行排序需要O(nlogn)时间,问题是我是否正在排序具有两个属性的对象列表,排序此列表的时间复杂度是多少?谢谢!
答案 0 :(得分:4)
@PaulMcKenzie评论中的简短回答是正确的,但对你的问题的真正答案更为微妙。
许多人做了你做过的事,把时间与其他效率措施混为一谈。几乎在所有情况下,当有人说&#34;排序为O(n log n)&#34;时,这是正确的。是 比较 的数量是O(n log n)。
我不想迂腐。邋analysis的分析可能会在实践中产生很大的问题。您无法声明任何排序都在O(n log n) 时间 中运行,而无需大量有关数据和运行算法的计算机的其他声明。理论论文通过陈述用于分析的标准机器模型来做到这一点。该模型说明了算法的低级操作所需的时间 - 例如,存储器访问,算术和比较。
在你的情况下,每次比较都需要一个常数来进行比较,所以只要比较本身是恒定时间 - 实际上对于固定宽度整数来说是真的 - 你就会处于良好的状态。
然而,像字符串排序这样简单的事情会改变这种情况。字符串比较本身具有可变成本。这取决于字符串长度!因此,使用&#34; good&#34;对字符串进行排序排序算法是O(nk log n),其中k是字符串的长度。
如果你要对可变长度数字进行排序(例如java BigInteger
),也不例外。
排序对复制成本也很敏感。即使您可以在恒定时间内比较对象,排序时间也取决于它们的大小。算法的不同之处在于需要在内存中移动对象的次数。有些人接受更多的比较以防止不必要的复制。实现细节:排序指针与对象可以改变渐近运行时间 - 时间交易的空间。
答案 1 :(得分:0)
大O符号实际上忽略了影响最小的因素
例如,如果您的复杂度为n+1
,则会使用n
而忽略1
。
所以答案是相同的n * log(n)
。
因为你的代码只添加了一个语句,它将被翻译成一条指令。
答案 2 :(得分:-1)