3

我已经阅读了很多关于大 O 表示法的内容,并且我有一个基本的了解。这是一个具体的问题,我希望能帮助我更好地理解它。

如果我有 100 个整数的数组(没有重复,并且随机生成)并且我使用 heapsort 对其进行排序,我知道 heapsort 的 big-O 表示法是 n lg n。对于 n = 100,计算结果为 100 × 6.64,大约为 664。

虽然我知道这是比较次数的上限,并且我的计数可能小于 664,但如果我试图找出 100 个随机数的堆排序数组的比较次数,它应该始终小于或等于664?

我正在尝试在我的堆排序中添加计数器以获得大 O 比较时间并得出疯狂的数字。我将继续解决它,但只是想验证我是否正确地考虑了上限。

谢谢!

4

2 回答 2

4

Big-O 表示法不会为您提供函数运行时的确切上限 - 相反,它会渐近地告诉您函数的运行时如何增长。如果一个函数的运行时间为 O(n log n),这意味着该函数的增长速度与函数 f(n) = n log n 大致相同。这意味着,例如,实际运行时间可能是 23 n log n + 17 n,或者可能是 0.05 n log n。因此,您不能使用堆排序为 O(n log n) 的事实来计算进行的比较次数。你需要更精确的分析。

碰巧您可以对堆排序进行非常精确的分析,但这需要您对算法进行更细致的分析。例如,您可以显示调用 make-heap 所需的比较次数最多为 3n,并且在重复调用 extract-min 期间进行的比较次数最多为 2n log (n + 1)(二叉堆有 log (n + 1) 层,并且在 n 个 extract-max 的每一层中,在每一层最多进行两次比较)。这给出了以 2n log (n + 1) + 3n 为上限的比较总数。

著名的Ω(n log n)排序障碍可用于获得匹配的下限。任何基于比较的排序算法,堆排序就是其中之一,必须至少使 log n!= n log n - n + O(log n) (这是斯特林的近似值)平均比较,因此在最坏的情况下需要进行至少 n log n - n 比较。(请注意,这实际上是 n log n,而不是 n log n 的某个常数倍数。您可以阅读 Ω(n log n) 障碍的证明,了解为什么会这样。)

希望这可以帮助!

于 2013-06-16T15:19:06.583 回答
3

假设您知道您的算法在对元素O( n log_2 n )进行排序时需要比较。n

这告诉您以下内容,并且告诉您以下内容:存在一个常数C,使得当n接近无穷大时,该算法只需要C * n * log_2 n比较即可。

它没有告诉您任何值可能需要的特定比较次数n——它告诉您随着元素数量的增长,所需的比较次数如何在限制范围内增长。

您不能使用排序算法的 Big-O 复杂性来证明有关特定有限行为的任何信息n,例如 100 个元素。对 100 个元素进行排序可能需要 64 次比较,或 664 次或 6.64 亿次。后者显然是不合理的,但 Big-O 在这里根本没有提供任何信息。

于 2013-06-16T15:12:51.793 回答