为何quicksort比mergesort更好?

我在接受采访时被问到这个问题。 他们都是O(nlogn),但大多数人使用Quicksort而不是Mergesort。 这是为何? html


#1楼

在全部条件相同的状况下,我但愿大多数人都能使用最方便的东西,并且每每是qsort(3)。 除了快速排序以外,已知数组上的快速排序很是快,就像mergesort是列表的常见选择同样。 java

我想知道为何看到基数或桶排序这么罕见。 它们是O(n),至少在链表上,所须要的只是将密钥转换为序数的一些方法。 (字符串和浮点数工做正常。) 算法

我认为缘由与计算机科学的教学方式有关。 我甚至不得不向算法分析的讲师证实,确实能够比O(n log(n))更快地排序。 (他有证据证实你不能比O(n log(n))更快地进行比较 ,这是真的。) 数组

在其余新闻中,浮点数能够按整数排序,但您必须在以后转换负数。 函数

编辑:实际上,这是一种更加恶毒的方式来整理浮点数 - 整数: http//www.stereopsis.com/radix.html 。 请注意,不管您实际使用哪一种排序算法,均可以使用位翻转技巧... 性能


#2楼

对于原始值的DualPivotQuickSort带来的变化,答案会略微倾向于快速排序。 它在JAVA 7中用于在java.util.Arrays中进行排序 ui

It is proved that for the Dual-Pivot Quicksort the average number of
comparisons is 2*n*ln(n), the average number of swaps is 0.8*n*ln(n),
whereas classical Quicksort algorithm has 2*n*ln(n) and 1*n*ln(n)
respectively. Full mathematical proof see in attached proof.txt
and proof_add.txt files. Theoretical results are also confirmed
by experimental counting of the operations.

你能够在这里找到JAVA7的实现 - http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/Arrays.java spa

关于DualPivotQuickSort的更多精彩阅读 - http://permalink.gmane.org/gmane.comp.java.openjdk.core-libs.devel/2628 code


#3楼

“然而大多数人使用Quicksort而不是Mergesort。为何会这样?” 视频

没有给出的一个心理缘由就是Quicksort更加巧妙地命名。 即良好的营销。

是的,具备三重分区的Quicksort多是最好的通用排序算法之一,可是没有克服“快速”排序听起来比“合并”排序更强大的事实。


#4楼

快速排序是最坏状况O(n ^ 2),可是,平均状况始终执行合并排序。 每一个算法都是O(nlogn),但你须要记住,在谈论Big O时,咱们忽略了较低的复杂因素。 当涉及常数因素时,快速排序比合并排序有显着改进。

合并排序还须要O(2n)内存,而快速排序能够就地完成(只须要O(n))。 这是快速排序一般优于合并排序的另外一个缘由。

额外信息:

当枢轴选择不当时,会发生最快的快速排序。 请考虑如下示例:

[5,4,3,2,1]

若是选择枢轴做为组中的最小或最大数字,则快速排序将在O(n ^ 2)中运行。 选择列表中最大或最小25%的元素的几率为0.5。 这使得算法成为一个良好的支点。 若是咱们采用典型的枢轴选择算法(好比选择一个随机元素),咱们就有0.5个机会为每一个枢轴选择一个好的枢轴。 对于大尺寸的集合,老是选择不良枢轴的几率是0.5 * n。 基于此几率,快速排序对于平均(和典型)状况是有效的。


#5楼

为何Quicksort好?

  • QuickSort在最坏的状况下采用N ^ 2和NlogN平均状况。 最糟糕的状况发生在数据排序时。 在排序开始以前,能够经过随机混洗来减轻这种状况。
  • QuickSort不会占用合并排序所需的额外内存。
  • 若是数据集很大且项目相同,则Quicksort的复杂性经过使用3路分区而下降。 更多相同的项目更好的排序。 若是全部项目都相同,则按线性时间排序。 [这是大多数库中的默认实现]

Quicksort老是比Mergesort好吗?

并非的。

  • Mergesort稳定但Quicksort不稳定。 所以,若是您须要输出稳定性,则可使用Mergesort。 在许多实际应用中须要稳定性。
  • 记忆如今很便宜。 所以,若是Mergesort使用的额外内存对您的应用程序并不重要,那么使用Mergesort没有任何害处。

注意:在java中,Arrays.sort()函数使用Quicksort做为基本数据类型,使用Mergesort做为对象数据类型。 由于对象消耗了内存开销,因此为Mergesort添加一点开销可能不是性能观点的任何问题。

参考 :观看Coursera第3周,普林斯顿算法课程的QuickSort视频

相关文章
相关标签/搜索