Java 什么';对具有两个属性的对象列表进行排序的时间复杂度是多少?

Java 什么';对具有两个属性的对象列表进行排序的时间复杂度是多少?,java,algorithm,sorting,Java,Algorithm,Sorting,假设我有一门课: ` ` 我想使用集合对间隔列表进行排序。排序()如下: Collections.sort(intervals, new Comparator<Interval>(){ @Override public int compare(Interval o1, Interval o2) { if (o1.start == o2.start) { return o1.end - o2.end; }

假设我有一门课: `

`

我想使用集合对间隔列表进行排序。排序()如下:

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;
        }
    }
});
Collections.sort(间隔,新比较器(){
@凌驾
公共整数比较(区间o1、区间o2){
如果(o1.start==o2.start){
返回o1.end-o2.end;
}
否则{
返回o1.start-o2.start;
}
}
});

我知道使用内置排序函数对数组进行排序需要O(nlogn)时间,问题是如果我对具有两个属性的对象列表进行排序,那么对该列表进行排序的时间复杂度是多少?谢谢

大O符号实际上忽略了最小的影响因素

例如,如果复杂性为
n+1
,则将使用
n
,而忽略
1

所以答案是相同的
n*log(n)

因为您的代码只添加了一条语句,它将被转换为一条指令。

它应该读取集合。sort()

此算法保证了n个log(n)性能。


注意:Comparator不会改变其复杂性,而不是使用循环

@PaulMcKenzie在评论中的简短回答是正确的,但您问题的真正答案更微妙

很多人做你做过的事情,把时间和其他效率指标混为一谈。几乎在所有情况下,当有人说“排序是O(n logn)”时,正确的是比较的数量是O(n logn)

我不是想装腔作势。草率的分析会在实践中产生大问题。如果没有一大堆关于数据和运行算法的机器的附加语句,就不能声称任何排序都是在O(nlogn)时间内运行的。理论论文通过陈述用于分析的标准机器模型来实现这一点。该模型说明了算法的低级操作所需的时间,例如内存访问、算法和比较

在您的例子中,每个比较都需要一个常数来进行比较,所以只要比较本身是常数时间——实际上对于固定宽度的整数是如此——您就处于良好状态

然而,像字符串排序这样简单的事情改变了这张图片。字符串比较本身具有可变成本。这取决于字符串长度!因此,使用“良好”排序算法对字符串进行排序是O(nk log n),其中k是字符串的长度

如果您正在对可变长度的数字进行排序(例如java
BigInteger
s),则同上


排序对复制成本也很敏感。即使可以在固定时间内比较对象,排序时间也将取决于对象的大小。算法的不同之处在于需要在内存中移动对象的次数。有些人接受更多的比较,以防止不必要的复制。一个实现细节:对指针和对象进行排序可以改变渐进的运行时间-一个时间交易的空间。

它的复杂性是相同的
(on*log(n))
。额外的
if
语句不会将对数排序转换为四次排序。感谢您的澄清!!“我现在明白了。”保罗·麦肯齐说得不准确。我想你的意思是
else
语句不会增加成本,但是如果
语句会将成本与每个新条件进行平方,那么额外的
语句会增加成本。请注意,使用
整数是一个好习惯。比较(a,b)
而不是
a-b
习惯用法,因为当a和b之间的差值大于
Integer.MAX\u值时,后者不起作用。(例如在比较-1和Integer.MAX_值时)。@mohsenmadi那么额外if语句的大O表示法是什么?如果用于比较的算法取决于被比较的元素的数量,那么比较器完全可以改变整个算法的复杂性。但这里的情况不是这样,比较本身是O(1)。是的,你是正确的,但我只是在上面讨论算法。谢谢@ErwinBolwidtOf当然,如果比较导致数据集上的另一组循环,那么比较会导致复杂性的改变。这里的情况不是这样的。如果我的回答是关于什么的,这个讨论就是一个例子。比较成本很重要。复印费也是一样。对不起,我弄错了
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;
        }
    }
});