[英]Are asymptotic notations flawed?
任何算法的最佳情况复杂度是算法完成其任务所需的最短时间。 我们知道合并排序、快速排序等算法的最佳情况复杂度是 Ω(n log(n)),它定义了这些算法的下限。
正如我们所知,在渐近符号中 -
O(n) + O(n log(n)) = O(n log(n))
还,
Ω(n) + Ω(n log(n)) = Ω(n log(n))
因此,如果在这些排序算法中,我们首先在 O(n) 时间内遍历整个数组以确定该数组是否已经按升序或降序排序,那么它们的平均情况和最坏情况复杂度将渐近保持不变。 但是他们最好的情况复杂性现在将变为Ω(n) 。
从逻辑上讲,我理解这些渐近符号的方式肯定存在缺陷,否则当渐近符号正在开发或流行以测量排序算法时,肯定有人会指出这一点。 我是否正确假设这是渐近符号中的一个似是而非的缺陷,还是我错过了一些渐近符号规则?
使用渐近复杂度作为速度度量肯定存在问题。 首先,显然常数很重要。 1000n
通常会比n log n
大得多,对于 n 的任何实际值, n
n^1000
肯定比2^n
大得多。 然而,事实证明,渐近复杂度通常是算法实际速度的一个相当好的指标。
你提出的问题也是正确的,但我不认为这是一个问题。 确实,在快速排序开始时进行简单的isSorted()
检查会将其最佳案例复杂度降低到Θ(n)
,但很少有人关心最佳案例性能。 事实上,许多常见问题的算法都可以修改为最佳情况线性,但这并不是很有用。
最后,请注意,这并不是渐近符号的真正缺陷。 进行随机猜测并验证猜测是否正确(例如通过猜测数组已经排序)通常确实可以提高最佳情况的性能,而对平均或最坏情况的影响很小,无论使用哪种表示法。
首先,您应该在脑海中区分情况(最佳、最差、平均等)和界限(上限、下限、O、Omega、Theta 等)。
让我们专注于冒泡排序,定义如下:
if array == null or array.length < 2 then return
do
swapped = false
for i = 0 to array.length - 2
if array[i] > array[i+1] then
swap(array, i, i+1)
swapped = true
until not swapped
该算法的最佳情况是排序数组,在这种情况下,下限 (Omega)、上限 (O) 和 Theta 界限都同意运行时由 f(n) = an 形式的 function 限制; 也就是说,T(n) = O(n)。 冒泡排序的最佳情况是线性的。
该算法的最坏情况是反向排序的数组。 在这种情况下,运行时间由 function 上下限定,例如 g(n) = bn^2; 在最坏的情况下,T(n) = O(n^2)。
您不会遗漏任何东西,算法具有不同的最坏情况和最佳情况运行时界限是完全正常的。 算法也很可能无法针对最佳情况进行优化,因为最佳情况通常不是我们担心的情况; 是的,归并排序可以首先检查数组是否已排序,但是在长度为 N 的所有可能的 arrays 的集合中,这些数组的数量相对较少。
此外,您可以选择谈论最坏情况下的下限或最佳情况下的上限。 这些事情不是我们通常关注的——而是关注最坏情况的上限,或者可能是最好情况的下限——但情况和边界是完全独立的事物,可以任意组合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.