拥有这个简单的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);
}
}
在不知道Collection.sort方法的复杂性的情况下,我如何计算该算法的复杂性?
我应该去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的输入,程序中有某种循环,或者对有问题的函数进行递归调用时,复杂性才是有趣的,所以运行时间取决于输入。正如桑杰夫·夏尔马所指出的,在这种情况下,寻找复杂性是荒谬的。