在我的教科书中,我看到以下内容:
定义算法的顺序
算法A是阶数f(n) - 表示为O(f(n)) - 如果常数k和n0存在使得A需要不超过k * f(n)个时间单位来解决大小为n> =的问题N0。
我理解:不同复杂性类的时间要求以不同的速度增长。例如,随着n值的增加,O(n)所需的时间比O(n2)生长得慢得多,O(n2)比O(n3)生长得更慢,等等。
我不明白:k和n0如何适合这个定义。
我已经看过了:
1)n> n0 - 意味着我们同意对于小n A可能需要多于k * f(n)的运算。例如。对于非常小的输入,冒泡排序可能比快速排序或合并排序更快。选择0作为下标完全取决于作者的偏好。
2)输入尺寸更大。
3)k是常数。假设一个算法对大小为n的输入执行1000 * n运算,因此它是O(n)。另一种算法需要5 * n ^ 2次操作来输入大小为n。这意味着对于大小为100的输入,第一个算法需要100,000个操作,第二个算法需要50,000个操作。因此,对于大约100的输入大小,你最好选择第二个,虽然它是二次的,第一个是线性的。在下图中你可以看到n0 = 200,因为只有n大于200的二次函数变得比线性更昂贵(这里我假设k等于1)。
所有这些条件都旨在简化O表示法,使简单和复杂操作之间的区别变得无声(例如,只要数字是有限的,您不关心操作是一个还是20个周期)。
n是问题大小,但是最好测量。因此,n0是特定常数n,特别是在该关系成立之后的阈值。具体价值与大哦无关,只对它的存在感兴趣。
k也是一个任意常数,它的裸存在(与n0一起)对于大哦很重要。
当然,人们也对较小的问题感兴趣,事实上,由于所涉及的常数,对于小问题而言,对于大问题的完美算法可能是非常低效的。