Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 快速排序算法——澄清_Algorithm_Sorting_Quicksort - Fatal编程技术网

Algorithm 快速排序算法——澄清

Algorithm 快速排序算法——澄清,algorithm,sorting,quicksort,Algorithm,Sorting,Quicksort,我看了不同的视频,读了不同的关于快速排序算法的文章 我知道它是如何工作的,如果我不知道的话,网上有很多资料供我查阅。我在这里遇到的问题是,我发现的一些文章声明如下(): 对数组重新排序,使值小于轴的所有元素位于轴的前面,而值大于轴的所有元素位于轴的后面(两种方式都可以使用相同的值)。在该分区之后,轴心处于其最终位置。这称为分区操作 其他一些来源,(): 我们交换元素,使得所有小于轴的元素都位于大于轴的元素之前 这两种算法有很大的不同。第一种方法使用枢轴拆分阵列,将较小的东西放在一边,较大的东西放

我看了不同的视频,读了不同的关于快速排序算法的文章

我知道它是如何工作的,如果我不知道的话,网上有很多资料供我查阅。我在这里遇到的问题是,我发现的一些文章声明如下():

对数组重新排序,使值小于轴的所有元素位于轴的前面,而值大于轴的所有元素位于轴的后面(两种方式都可以使用相同的值)。在该分区之后,轴心处于其最终位置。这称为分区操作

其他一些来源,():

我们交换元素,使得所有小于轴的元素都位于大于轴的元素之前

这两种算法有很大的不同。第一种方法使用枢轴拆分阵列,将较小的东西放在一边,较大的东西放在另一边

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

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

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

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


我发现许多相互矛盾的观点,我想知道这是否重要,但我想知道是否有一种正确的方法来实现它,或者它可以有所不同。

两种主要的快速排序分区方案是Lomuto和Hoare。wiki文章中的伪代码解释了这两种情况:

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

对于Lomuto方案,枢轴位于子数组的左端或右端,并且有一个将枢轴放置到位的最终交换。对于Lomuto,pivot元素不包括在递归调用中

对于Hoare方案,由于算法的工作方式,轴心最终到位。但是,轴心最终成为左分区的最后一个元素或右分区的第一个元素。可以添加额外的代码以将pivot元素从递归中排除,但结果会稍微慢一点。霍尔方案通常比洛穆托更快

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

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

另一种方法是使用类似introsort的混合排序,如果递归级别超过某个阈值,它将切换到堆排序


两种主要的快速排序分区方案是Lomuto和Hoare。wiki文章中的伪代码解释了这两种情况:

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

对于Lomuto方案,枢轴位于子数组的左端或右端,并且有一个将枢轴放置到位的最终交换。对于Lomuto,pivot元素不包括在递归调用中

对于Hoare方案,由于算法的工作方式,轴心最终到位。但是,轴心最终成为左分区的最后一个元素或右分区的第一个元素。可以添加额外的代码以将pivot元素从递归中排除,但结果会稍微慢一点。霍尔方案通常比洛穆托更快

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

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

另一种方法是使用类似introsort的混合排序,如果递归级别超过某个阈值,它将切换到堆排序


来自hackerrank的语句只是不完整,当然元素是围绕pivot交换的,否则数组将不完整sorted@IlyaBursov链接中的视频很明显没有在轴上分裂。它使用的是不同的分区技术。因此pivot总是成为分割数组的数字?@NicolaPedretti维基百科页面很好地描述了不同的分区方案。看起来视频选择了Hoare分区:@MarkMeyer刚刚看了视频,你说得对-他们正在使用hackerrank的Hoare分区方案声明不完整,当然是eleme