当所有元素相同时,Quicksort的复杂性?

时间:2011-02-26 11:23:13

标签: c algorithm complexity-theory

我有一组N个相同的数字。我正在应用快速排序。 在这种情况下,排序的时间复杂度应该是多少。

我对这个问题感到很惊讶,但没有得到确切的解释。

任何帮助都将不胜感激。

6 个答案:

答案 0 :(得分:31)

这取决于Quicksort的实现。分为2个(<>=)部分的传统实现在相同输入上将具有O(n*n)。虽然不会发生交换,但它会导致n递归调用 - 每个调用都需要与pivot和n-recursionDepth元素进行比较。即需要进行O(n*n)比较

但是有一个简单的变体分为3组(<=>)。在这种情况下,此变体的性能为O(n) - 而不是选择透视,交换然后在0pivotIndex-1pivotIndex+1n递归,它将会把所有东西等于枢轴的交换放到'中间'分区(在所有相同输入的情况下总是意味着交换自己,即无操作)意味着在这种特殊情况下调用堆栈只有1深度n比较和没有互换发生。我相信这个变种至少已经进入linux上的标准库。

答案 1 :(得分:5)

快速排序的表现取决于枢轴选择。选择的枢轴越接近中间元素,快速排序的性能就越好。

在这种特殊情况下,您很幸运 - 您选择的轴将始终为 中位数,因为所有值都相同。因此,快速排序的分区步骤将永远不必交换元素,并且两个指针将恰好在中间相遇。因此,这两个子问题的大小只有一半 - 给你一个完美的O(n log n)

更具体一点,这取决于分区步骤的实施情​​况。循环不变只需要确保较小的元素在左手子问题中,而较大的元素在右手子问题中。无法保证分区实现永远不会交换相同的元素。但它总是不必要的工作,所以没有聪明的实现应该这样做:leftright指针永远不会检测到相应的枢轴反转(即你永远不会遇到*left > pivot && *right < pivot的情况)所以left指针将递增,right指针将逐步递减,它们最终会在中间相遇,生成大小为n/2的子问题。

答案 2 :(得分:2)

这取决于具体的实施方式。

如果只有一种比较(≤或&lt;)来确定其他元素相对于枢轴的位置,它们将全部进入其中一个分区,你将获得O( n < / em> 2 )性能,因为问题大小每步只会减少1个。

算法listed here就是一个例子(附图说明了不同的算法)。

如果有两种比较,例如&lt;对于左边的元素和&gt;对于右边的元素,就像在双指针实现中的情况一样,如果你注意在步骤中移动指针,那么你可能会得到完美的O( n log n )性能,因为一半相等的元素将在两个分区中均匀分割。

上面链接中的插图使用了一种不会逐步移动指针的算法,因此您的性能仍然不佳(请参阅“少数独特”案例)。

因此,在实施算法时,是否考虑到这一特殊情况。

实际实现通常会处理更广泛的特殊情况:如果分区步骤中没有交换,它们会假设数据几乎已经排序,并使用插入排序,这样可以提供更好的O( n )在所有相等元素的情况下。

答案 3 :(得分:1)

tobyodavies提供了正确的解决方案。当所有键都相等时,它会处理大小写并在O(n)时间内完成。 它与我们在荷兰国旗问题中的划分相同

http://en.wikipedia.org/wiki/Dutch_national_flag_problem

分享来自princeton的代码

http://algs4.cs.princeton.edu/23quicksort/Quick3way.java.html

答案 4 :(得分:0)

如果实施双向分区算法,则每一步都会将数组减半。这是因为当遇到相同的键时,扫描停止。结果,在每个步骤中,分区元素将位于子阵列的中心,从而在每个后续递归调用中将阵列减半。现在,这种情况类似于mergesort情况,它使用~N lg N比较来排序N个元素的数组。对于重复键而言,Quicksort的传统双向分区算法使用~N lg N进行比较,从而遵循线性方法。

答案 5 :(得分:0)

快速排序代码是使用“分区”和“快速排序”功能完成的。

基本上,实现快速排序有两种最佳方式。

这两者的区别只是“分区”功能,

1.Lomuto

2.霍尔

使用诸如上述 Lomuto 分区方案的分区算法(即使是选择好的主元值),快速排序对于包含许多重复元素的输入表现出较差的性能。当所有输入元素都相等时,问题就很明显了:在每次递归时,左分区为空(没有输入值小于主元),而右分区仅减少了一个元素(删除了主元)。因此,Lomuto 分区方案需要二次时间来对相等值的数组进行排序。

因此,使用 Lomuto 分区算法需要 O(n^2) 时间。

通过使用 Hoare 分区算法,我们得到了所有数组元素相等的最佳情况。时间复杂度为 O(n)。

参考:https://en.wikipedia.org/wiki/Quicksort