Big O(n logn) is not preferable over the O(n^2)
任何算法示例,什么时候我们更喜欢大的O(n^2)时间复杂度而不是O(n logn)?我在某个地方见过这个问题,但没有找到答案。
对于一个大问题,O(n log n)总是会胜过O(n^2)。对于一个小问题,大O符号隐藏的常量因子可能会导致您更喜欢O(n^2)算法。例如,O(n log n)快速排序比O(n^2)插入排序快,但是一些快速排序实现在分区变小(少于10个元素)时切换到插入排序。
选择时间复杂度较高的算法有几个原因:
- 速度:渐进复杂性只适用于大于某个n_0的n值。此外,它还假定下面的某台机器只部分匹配具有多个缓存级别和受限内存的真实机器。
- 空间:有些算法比其他算法需要更多的空间,因此无法实现。此外,这可能只会影响实际机器的速度。例如,引用的位置对缓存命中或未命中有影响,这就是QuickSort比MergeSort执行得更好的原因。
- 实现的复杂性:在某些情况下,性能的损失是可以忽略的,但开发时间不是。
许多幼稚的O(n^2)算法在小输入上比它们更复杂的O(n log(n))算法更快。
例如,gnu mp bignum库有一个非常优化的乘法实现。但对于由几十个单词组成的数字,它只使用课本乘法(最好的阈值很大程度上取决于机器)。事实上,药品生产质量管理规范通过一系列最快的X尺寸算法进行转换。
一种可能性是O(n logn)算法是递归的,但是您可以迭代地编程O(n^2),并且您必须使用的编程语言不支持递归。
"preferred"在这里是相对的btw。如果数据集足够大,您可以使用自己的堆栈变量来模拟递归,您可以在迭代实现的"recursive"算法版本中操作该堆栈变量(我们必须在Guy Steele在CMU的比较编程类中做这个练习)。