Algorithm 对于较小的输入大小,常数在时间复杂度方面是否重要?怎么用?

Algorithm 对于较小的输入大小,常数在时间复杂度方面是否重要?怎么用?,algorithm,time-complexity,big-o,complexity-theory,Algorithm,Time Complexity,Big O,Complexity Theory,我正在听一些关于时间复杂性的讲座&在这个链接上,作者在4:50解释说常数在很多情况下都很重要,因为它们的输入量很小。请解释一下假设有两种算法的实际复杂度分别为100n和2n2,它们是O(n)和O(n2)。对于n=2,它们将分别需要200和8个CPU周期来执行。但对于大于50的n值,100n算法的性能始终优于2n2算法 通过这种方式,我们可以看到,对于较小的输入,大O可能不是一个很好的算法判断,常数发挥着重要作用,特别是当它们与输入相比相当大时 同样,当处理100+n和2+n2类情况的时间复杂性

我正在听一些关于时间复杂性的讲座&在这个链接上,作者在4:50解释说常数在很多情况下都很重要,因为它们的输入量很小。请解释一下

假设有两种算法的实际复杂度分别为100n和2n2,它们是O(n)和O(n2)。对于n=2,它们将分别需要200和8个CPU周期来执行。但对于大于50的n值,100n算法的性能始终优于2n2算法

通过这种方式,我们可以看到,对于较小的输入,大O可能不是一个很好的算法判断,常数发挥着重要作用,特别是当它们与输入相比相当大时



同样,当处理100+n和2+n2类情况的时间复杂性时,您可以理解结果。对于不足以超过常数影响的n值,实际执行时间可能最终由常数而不是输入值n决定。

对于时间复杂度的数学术语,它并不重要

然而,如果你有大的常数,你的程序可能会比复杂度差的程序慢,即使它的复杂度好。这是很明显的,想象一下睡一个小时,你的程序需要一个长的,大的常数。但它的复杂性类可能很好,因为常量并不重要

为什么它们不重要?因为对于每一个复杂度更差的程序,都会有一个输入(大输入),它们在某个时候会变慢


以下是一个例子:

好的复杂性
O(1)
,但速度慢:

void method() {
    sleep(60 * 60 * 1_000); // 1 hour
}
复杂性越差
O(n)
,小输入速度越快:

void method(int n) {
    for (int i = 0; i < n; i++) {
        sleep(1_000); // 1 second
    }
}
void方法(int n){
对于(int i=0;i
但是,如果您输入
n>60*60
,第二种方法将变慢


您不应该将时间复杂性与实际可测量的运行时间混淆,这是一个巨大的差异

时间复杂度约为渐近界,请参见O(g)
中的f定义:


当我研究算法及其复杂性时,我们的教授简要地解释了常数非常重要。在复杂性理论中,有两种主要的符号来解释复杂性。第一个是BigO,第二个是tild符号

假设您实现了一个优先级队列(使用heap),它对每个项目的insert进行
2lgN
比较以删除最大元素和
1+logN
。现在人们实际做的是删除
2logN
并将其写为
O(logN)
,但这是不对的,因为插入元素只需要
1+logN
,当删除元素时,需要重新平衡队列(sink和swim)函数

如果您将
~2logN
写成
O(logN)
,那么这意味着您只计算一个函数的复杂性,要么是swim,要么是sink

作为参考,我将补充一点,在一些顶级大学,大多数教授使用
~
符号


BigO可能是有害的。作者的一本书使用了
~
,并解释了他为什么喜欢它。

bigO的基本概念是渐近分析,意思是:n->inf.表示小n;理论和实践之间的差距可能会变得巨大。@如果用户回答了您的问题,请同时接受他的回答()。如果没有,请说明还有什么问题没有回答,这是StackOverflow的一个关键部分,非常感谢。@Zabuza:谢谢你指出。我做到了,虽然100不是一个常数,但它是一个常数因子。我认为OP(和视频)谈论的是O(100+n)之类的东西,但同样的观点也适用于这里。@tobias_k:谢谢你的评论。我没有看到视频,而是用我对这个问题的直觉写下了答案。我现在补充了你指出的内容。