例如,假设我有一个算法是O(n),算法是一个摊销的O(n)。可以公平地说,在严格意义上说,非摊销算法总是会比摊销算法快或快吗?或者是否有任何理由更喜欢分期付款的版本(忽略代码简单或易于实现)?
答案 0 :(得分:7)
答案 1 :(得分:6)
或者是否有任何理由更喜欢分期付款的版本
较小的常数。
答案 2 :(得分:5)
O(n)算法和摊销的O(n)算法之间的主要区别在于您对摊销的O(n)算法的最坏情况行为一无所知。在实践中,这并不常见:如果您的算法运行多次,那么您可以依靠平均律来平衡一些不良情况,如果您的算法没有运行很多次,那么你根本不可能遇到最糟糕的情况。
“摊销”这个词应该重要的唯一情况是,由于某种原因你不能接受偶尔的不良表现。例如,在GUI应用程序中,您可以愉快地放弃一些平均情况下的性能,以换取保证,当用户坐在那里并感到无聊时,您永远不会陷入困境并停止响应。在这些应用程序中,您希望确保即使是最坏情况的行为也适用于任何可能导致GUI停止响应的代码。
但是,大多数时候,你不需要担心摊销的O(n)与O(n),你可以担心常数因素是什么(正如其他人已经说过的那样)。
答案 3 :(得分:1)
Big O表示法会告诉您算法如何随着输入的增加而变化。 它不是分析代码的捷径。
对于程序中的所有n,更好的算法可能是O(n ^ 2),因为O(n)中的常量更大。
因此,您选择的算法实际上取决于您的输入大小更快的算法。我想你的问题的答案是在你的程序中分析两种算法,然后决定哪种算法更快。
答案 4 :(得分:1)
需要分摊算法的典型例子是std :: vector,其插入分期为O(1)。
使用分期算法的一些原因:
答案 5 :(得分:0)
严格地说,big-O不够精确,所以能够说O(n)的算法比具有摊销的O(n)的算法快。想一想。如果您在复杂性分析中降低了保真度,则常数因素可能会显着不同,从而使摊销版本更快。
此外,摊销的影响往往取决于使用。例如,如果您使用哈希表,则摊销的影响将在很大程度上取决于您的添加操作的比率。因此,如果您添加1000个条目,然后进行十亿次查找,那么您必须重新进行几次重复的事实并没有太大的区别。但是如果你不断添加条目,那么重组的成本可能会增加。
这就是为什么摊销与最坏情况不同的原因。 Big-O反映了最糟糕的情况,而摊销让你说“每个x中的一个会受到打击,而x足够大,无关紧要。”此外,如果您考虑插入哈希表中的示例,x会根据某个常量增长。因此,如果你有一个以100个桶开头的哈希表,并且每次重复都会加倍,那么重新进行的渐进式渐渐变得越来越远。此外,具有摊销复杂性的算法的绝对最坏情况复杂性取决于先前的调用,而在像平均情况这样的度量中,调用被认为是独立的。