为什么Big O表示法中没有阵列/堆栈/队列和其他数据结构的最佳案例?

时间:2017-02-12 21:55:46

标签: java data-structures

我正在阅读这个备忘单https://www.packtpub.com/sites/default/files/downloads/4874OS_Appendix_Big_O_Cheat_Sheet.pdf,我想知道为什么网站上没有提到最好的案例。为什么只有平均和最差的情况?

1 个答案:

答案 0 :(得分:4)

主要是出于同样的原因,您购买汽车保险医疗保险,但不要购买赢得彩票保险我是健康保险:防范异常(或恶意)大型下行异常事件是有价值的,但没有必要&#34 ;保护"反对类似的上升事件。

次要原因是,与最坏情况保证不同,没有输入将触发行为,"最佳情况"如果没有进一步表征究竟是什么输入触发最佳情况,那么保证是非常有用的。许多算法实现确实包含此类信息,作为额外细粒度性能保证的一部分,但这主要是在经典复杂性分析之外。

下行保险

这一部分假设"期望"的有用性。复杂性是显而易见的 - 如果您的输入与 average-case 复杂性分析中假设的分布匹配,则应该期望的性能。这自然引发了一个问题:为什么要包括(不太可能的)最坏情况分析,而不包括表面对称最佳情况分析。 一般来说,最好的情况肯定是可以计算的 1 并且它们倾向于聚集在两个值:O(1)(例如,对于大多数结构操作)或O(n)(对于至少算法)需要检查他们的所有输入,如果他们有一个特殊情况来检测输入已经是所需的格式),那么最好的情况并不重要。通常算法甚至不会对最佳情况进行特殊处理,并且平均和最佳情况的复杂性是相同的。

基本上,在选择算法时,您应该期望平均情况,平均。然后你必须看一下异常值:在最坏的情况下会发生什么,最好的情况呢?

最坏情况非常重要,因为如果您的行为通常n*lg(n)但偶尔会有n!2^n甚至n^5行为,它可能会删除您的应用程序,使您的服务不可用等等。因此,最糟糕的情况值得考虑,无论是对于无意中触发它的输入,还是对恶意的解释使用可能会故意触发它。

在最好的情况下,您有一些行为与平均情况相关或更好。这并不重要。你已经在设计一个通常的结果是平均情况的系统,所以如果你有一些非常奇怪的输入恰好触发了最好的情况,这很酷 - 但它并不是你的核心标准。 #39; d用于选择系统,因为它是一个异常值。

表征最佳案例输入

现在,您可能会认为您的特定输入会一直触发最佳情况,因此最佳情况下的复杂性非常重要。问题是,单独的最佳案例复杂性并不足以保证任何事情。它只是告诉你,至少一个输入,这是复杂性,并没有告诉你这类输入是什么。你必须知道具体算法的细节才能弄明白。您可以轻松做出错误的假设:例如,如果排序算法具有O(n)最佳案例复杂性,您可能会认为它是针对已排序的输入,对吧?事实上,它可能适用于密集输入"它使用基数排序,但然后回退到合并/快速/任何排序的稀疏或非数字输入。

一旦你接受了最好的情况"仅仅是不够,你可以为你的特定输入表征算法的性能。对于某些特定的输入分布,它会将其转换回平均值分析(所有平均情况分析都需要有一些假定的输入分布,并且"均匀随机"是典型的)。此时,您可以完全省略O-notation,只是描述感兴趣平台上的实际运行时间。

另一方面,最坏情况的复杂性并不存在这个问题 - 它可以保证您不存在任何输入,从而触发最坏情况的行为。这种保证非常有用。至少存在一个输入的最佳保证,该算法非常快,并没有多大帮助。

最后,如果发布的最佳案例确实是一个重要的选择标准,那么大多数算法都可以简单地将单个已知输入编码到算法中,该算法返回已知输出,性能损失最小(on另一方面,检测一组通常有用的特殊情况以获得良好的性能通常会减慢非最佳用途。)

主要是关于什么有趣...

公平地说,你经常找到列出的最佳案例复杂性,可能只是出于对称性的要求,或者因为它很容易实现。维基百科肯定lists best-cases用于排序算法以及其他案例。所以,他们不会存在(因为你暗示在你的标题中)只是因为你发现.pdf并没有列出它们,但是主要是因为他们并不感兴趣。

1 在许多情况下,它们比平均情况(通常是最困难的)或最坏的情况更容易计算,通常很容易。这是您没有看到列出的最佳案例复杂性的另一个原因:通常通过检查来证明这一点。您可以认为最佳案例复杂性的第三个原因并不重要。