Quicksort算法-澄清

时间:2018-08-16 01:36:41

标签: algorithm sorting quicksort

我一直在看不同的视频,并阅读有关quicksort算法的不同文章。

我了解它是如何工作的,如果没有,我可以在网上找到很多资料。我在这里遇到的问题是,我发现的某些文章指出以下内容(from wikipedia):

  

对数组重新排序,以使所有值小于枢轴的元素都位于枢轴之前,而所有值大于枢轴的元素都位于枢轴之后(相等的值可以任意选择)。分割之后,枢轴处于其最终位置。这称为分区操作。

其他一些来源,(hackerrank video):

  

我们围绕元素交换元素,以使所有小于枢轴的元素都位于大于枢轴的元素之前

这两种算法有很大的不同。第一个使用枢轴拆分数组,将一侧较小的所有对象放到另一侧。

第二个元素将与轴本身无关,但是它将确保所有小于轴的元素都位于较大的元素之前。甚至没有提到枢轴结束的地方。

因此,如果这是要排序[3,15,4,4,8,12]的数组,并且枢轴是8

解决方案1:[3、4、8、15、12]

解决方案2:[3、8、4、15、12]

我发现了很多相互矛盾的意见,不知道这是否重要,但我想知道是否有正确的实施方法,或者它可能会有所不同。

1 个答案:

答案 0 :(得分:2)

两个主要的快速排序分区方案是Lomuto和Hoare。两者均在Wiki文章中的伪代码中进行了解释:

https://en.wikipedia.org/wiki/Quicksort#Lomuto_partition_scheme

https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme

对于这两种方案,每个分区步骤都将枢轴置于其最终排序位置。等同于枢轴的元素可以在分区步骤后最终在左侧或右侧分区中结束(但枢轴元素在其正确位置结束)。

对于Lomuto方案,枢轴位于子数组的左端或右端,最后进行了一次交换以将枢轴放置到位。对于Lomuto,枢轴元素不包含在递归调用中。

对于Hoare方案,由于算法的工作原理,枢轴最终就位。但是,枢轴最终以左分区的最后一个元素或右分区的第一个元素结尾。可以添加额外的代码以将枢轴元素排除在递归之外,但最终会稍微慢一些。 Hoare方案通常比Lomuto快。

为避免在简单的数据模式(如已排序的数据,反向排序的数据)上出现最坏情况O(n ^ 2)时间复杂度,可以在开始时使用三个中位数,对a中的第一个,中间和最后一个元素进行排序子数组,然后使用中间元素作为枢轴。另一种选择是选择一个随机枢轴,但是生成随机索引通常涉及乘法,加法和除法(对于模),这增加了开销。其他方案,例如中位数的中位数,可以保证O(n log(n))的时间复杂性,但是恒定因子开销是标准方案的倍数。

https://en.wikipedia.org/wiki/Median_of_medians

通过在分区步骤中仅使用两个分区中较小的分区的递归,然后循环返回以处理较大的分区,可以将最坏情况的堆栈复杂度限制为O(log(n))。这不能避免时间复杂度O(n ^ 2)。

一种替代方法是使用诸如introsort的混合排序,如果递归级别超过某个阈值,该混合排序将切换到堆排序。

https://en.wikipedia.org/wiki/Introsort