除了显而易见的“当有很多元素时它会更快”。什么时候使用简单的排序算法(0(N ^ 2))与高级算法(O(N log N))相比更合适?
我已经阅读了很多关于例如插入排序是首选的,当你有一个几乎排序的小数组,因为你得到了最好的情况N.为什么使用quicksort不好,例如,当你'说了20个元素。不仅仅是插入或快速,而是何时以及为什么与高级算法相比,更简单的算法是有用的?
编辑:如果我们正在使用例如数组,那么我们拥有哪些数据输入是否重要?如对象或原始类型(Integer)。
答案 0 :(得分:4)
对于大的N 值,大哦表示法捕获算法的运行时成本。对于小值,测量算法的运行时效果较差。
从一种算法到另一种算法的实际转换并非易事。对于大N,N的影响确实占主导地位。对于较小的数字,更复杂的效果变得非常重要。例如,某些算法具有更好的缓存一致性。当您对数据有所了解时,其他人最好(例如,当数据接近排序时,插入排序的示例)。
余额也随着时间而变化。过去,CPU速度和内存速度更加接近。缓存一致性问题不是问题。在现代,CPU速度通常会留下内存总线,因此缓存一致性更重要。
因此,当你应该使用一种算法而不是另一种算法时,没有一个明确且干燥的答案。唯一可靠的答案是分析您的代码并查看。
为了娱乐:几年前我一直在关注动态不相交的森林问题。我遇到了一篇最先进的论文,允许某些操作以像O(log log N / log ^ 4N)这样愚蠢的东西完成。他们做了一些非常精彩的数学计算,但有一个问题。操作非常昂贵,对于我的50-100个节点的图表,它比我最终使用的O(n log n)解决方案慢得多。对于在500,000多个节点的图表上运行的人来说,该论文的解决方案更为重要。
答案 1 :(得分:1)
超过99%的时间,您根本不应该实施排序算法。
而是使用您所用语言的标准库中的标准排序算法。在一行代码中,您可以使用经过测试和优化的实现O(n log(n))
。它可能会实现你不会想到的技巧。
对于外部排序,我不时使用Unix sort
实用程序。除了我需要让它表现出来的非直观LC_ALL=C
环境变量之外,它非常有用。
在您实际需要实施自己的排序算法的任何其他情况下,您实施的内容将由您的精确需求驱动。在二十年的编程中,我只需要处理一次生产代码。 (这是因为出于一系列复杂的原因,我需要在一台机器上对压缩数据进行排序,这台机器上没有足够的磁盘空间来存储未压缩的数据。我使用了合并排序。)
答案 2 :(得分:0)
编程排序算法时,您必须考虑实施实际算法的工作量与实际算法的实际速度。对于大O,实现高级算法的时间将超过排序所需的时间。对于小O,例如20-100项,差异很小,因此采用更简单的路线要好得多。
答案 3 :(得分:0)
首先,O-Notation让您了解最糟糕的情况。因此,如果数组接近排序,则执行时间可能接近线性时间,因此它比快速排序更好。 如果n足够小,我们会考虑其他方面。由于调用了所有递归,因此Quick-sort等算法可能会变慢。此时,它取决于操作系统如何处理递归,这种递归最终会比插入排序中所需的简单算术运算慢。更不用说递归算法所需的额外内存空间了。