计算包含预定义方法的算法复杂性



拥有这个简单的Java代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Simple {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(5);
        list.add(4);
        list.add(3);
        Collections.sort(list);
    }
} 
  1. 在不知道Collection.sort方法的复杂性的情况下,我如何计算该算法的复杂性?

  2. 我应该去java文档中搜索Collection.sort源代码,然后计算它的复杂性吗?

注意:Collection.sort只是预定义方法的一个示例。

感谢

在不知道System.out.println方法的复杂性的情况下,如何计算该算法的复杂性?

严格地说,你不能。

另一方面,在算法分析中包含I/O的详细复杂性是不正常的做法。通常,我们假设I/O的行为方式通常被理解为。。。因为真正的复杂性分析将是棘手的。

在实践中,假设简单I/O(像这样)具有O(N)的复杂性,其中N是读取或写入的字节/字符数。

我应该去java文档中搜索System.out.println源代码,然后计算它的复杂性吗?

没有。请参见上文。


可以理解,但是如果我调用排序预定义的java方法呢?

Collections.sort(List<?>)的javadoc说:

此实现遵循List.sort(Comparator)方法,使用指定的列表和null比较器。

反过来说:

实现说明:此实现是一种稳定、自适应、迭代的合并排序,当输入数组部分排序时,需要的比较次数远少于n次lg(n),而当输入数组随机排序时,它提供了传统合并排序的性能。如果输入数组几乎是排序的,那么实现需要大约n个比较。临时存储要求各不相同,从几乎排序的输入数组的小常数到随机排序的输入阵列的n/2对象引用。


通常,要确定标准类库中类的复杂性,请阅读javadoc,如果javadoc没有说明,则定位并分析源代码。。。或者根据您对实际使用的数据结构的了解做出合理的假设。

具体情况应决定您的复杂性分析是否需要严格。如果不需要严谨,你可以在分析中走捷径。。。如果你得到正确的答案:-)

无论哪种情况,都要注意算法几乎总是"实现细节",性能和空间复杂性(至少在理论上)会发生变化。

例如,这个helloworld程序具有恒定的时间复杂性,因为没有输入。在打印字符串时,实际上并没有进行任何计算。

样本没有任何输入,所以O是一个常数,或者O(1)。例如,只有当你有一个大小为N的输入,程序中有某种循环,或者对有问题的函数进行递归调用时,复杂性才是有趣的,所以运行时间取决于输入。正如桑杰夫·夏尔马所指出的,在这种情况下,寻找复杂性是荒谬的。

最新更新