Answers:
这实际上是一个深层次的问题,有一些方法性的和务实的答案。我假设您想了解手头的算法。如果您想知道哪种算法在给定输入下的给定机器上效果更好,请继续并测量运行时间。如果要比较给定算法的编译器质量,请继续并测量运行时间。要了解有关该算法的知识,请不要这样做。
让我首先说明为什么使用运行时不是一个好主意。
我希望这些使您相信,运行时是比较算法的可怕方法,并且需要一些通用的抽象方法来调查算法运行时。
接下来是问题的第二部分。为什么我们使用比较或类似的基本运算?
易分析性
假设您想进行形式分析,则必须能够进行。计算单个语句的技术性很强,有时甚至很难。尽管如此,仍有一些人(例如Knuth)这样做。仅计算某些语句(支配运行时的语句)更加容易。出于相同的原因,我们经常“仅”调查(上限)最坏情况下的运行时。
优势
所选操作主导运行时间。这并不意味着它贡献了最多的运行时间-比较显然没有作用,例如在对单词大小的整数进行排序时在Quicksort中。但是它们执行得最频繁,因此通过对它们进行计数,您可以计算出算法中执行最频繁的部分的运行频率。因此,您的渐近运行时与主要基本运算的数量成正比。这就是为什么即使我们只计算比较,我们也可以轻松使用Landau表示法和“运行时”一词。
请注意,计数多个操作可能很有用。例如,某些Quicksort变体进行比较的次数多,但交换次数却少(平均)。
值得一说的是,在完成所有理论之后,您可能希望重新访问运行时,以验证理论所做的预测是正确的。如果它们没有用,那么您的理论(在实践中)将无用,必须加以扩展。内存层次结构是您首先意识到的重要内容之一,但是在基本分析中却没有。
这是因为运行算法的总时间取决于运行该算法的硬件以及其他因素。如果一个在奔腾4上运行而另一个在Core i7上运行,则比较两种算法是不可靠的。不仅如此,还可以说您都在同一台计算机上运行。两者的处理器时间相同是什么意思?如果某个其他进程的优先级高于其中一种算法的进程,会发生什么情况?
为了克服这个问题,我们将这个总时间与完成时间分开,而是根据算法的扩展程度进行比较。您可能已经在研究论文中注意到了诸如O(1)或O(n ^ 2)之类的符号。如果您有兴趣查看Big O标记,这可能需要更多阅读。
由于其他答案解释了为什么我们要根据基本运算的数量来分析运行时,因此让我提供一些原因,说明为什么比较是许多(并非全部)排序算法的正确指标: