【问题标题】:Quicksort: pivoting scenarios快速排序:旋转场景
【发布时间】:2021-09-13 23:59:30
【问题描述】:

据我所知,如果您对近乎排序的列表进行排序,中间元素枢轴会比前面元素枢轴更好。在哪种情况下选择第一个元素作为枢轴比选择中间元素作为枢轴更有效?

我知道从三个中选取中值通常是最好的方法,但是有没有例外的情况是选择一个固定的枢轴,例如第一个或中间元素会更有效?

任何帮助将不胜感激。

【问题讨论】:

  • 最好选择的元素是中位数,无论它在列表中的哪个位置。
  • 如果你想阅读所有血腥的细节,你可以试试 Andrei Alexandrescu 的Fast Deterministic Selection。

标签: algorithm sorting quicksort


【解决方案1】:

据我所知,如果您对近乎排序的列表进行排序,中间元素枢轴会比前面元素枢轴更好。

当为每个分区选择的枢轴恰好是整个分区的中值时,快速排序性能最佳。所以是的,如果输入已经接近排序,那么选择每个分区的位置中间元素作为枢轴将产生对最佳性能的良好近似。当然,在这种情况下,插入排序可能会做得更好。

在哪种情况下选择第一个元素作为枢轴比选择中间元素作为枢轴更有效?

如果您假设输入是一致随机的,那么仅基于索引的枢轴选择方法不会比其他任何方法更好或更差。但是对于任何具有已知的确定性分区方案的快速排序实现,都可以构造为该方案引发最坏可能行为的输入。对于大多数这样的分区方案,麦芽​​汁情况的行为是元素数量的二次方。我不能随便描述一个会对中间元素枢轴快速排序产生影响的输入,* 但我向你保证,有一些。任何其他枢轴选择方法都可以改进大多数此类输入。

我知道选择三个中位数通常是最好的方法

3 的中位数在多种情况下是一种良好的方法。至于最好的,这在一定程度上取决于你所追求的。

但是有没有例外,选择一个固定的枢轴,比如第一个或中间元素会更有效?

3 的中位数也不例外我上面所说的。可以构建所谓的“三中位数杀手”序列,从 M3 快速排序中引发最坏情况的行为,并且最坏情况的行为是二次的。对于此类输入,几乎任何其他枢轴选择方法都更好。

另一方面,随机枢轴选择相对常见。从概率上讲,它避免了二次行为,随着输入大小的增加,二次缩小的可能性。并且或多或少不可能有意构建一个随机枢轴杀手序列(这样做需要枢轴选择依赖于攻击者知道其细节和初始状态的确定性(伪)RNG实现)。

另一方面,中位数的中位数实现起来更复杂,而且平均速度有点慢,但它的区别在于将 O(n log n) 最坏情况的行为传递给其他仔细实现的快速排序。

还有其他选择。


* 具有大多数元素相同的输入可以驱动许多快速排序实现二次,但这不是枢轴选择方案的特征,它可以独立于枢轴选择方案来解决。

【讨论】:

  • 重复元素会导致 Lomuto 分区方案变差,但会导致 Hoare 分区方案变好。
  • 这取决于细节,@rcgldr。当面对全等元素输入时,霍尔分区的某些实现会将所有元素放在枢轴的同一侧,从而演变为二次行为。
  • 我的意思是Hoare的标准实现,比如wiki example。通常,Hoare 分区方案会将枢轴和任何等于枢轴的值放在任一侧。随着副本数量的增加,它们最终会更均匀地分布在两侧,并且分区更接近于中间分裂。在所有重复的情况下,每个分区步骤在中间分裂,O(log2(n)),尽管会发生不必要的相等元素交换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-05
  • 1970-01-01
  • 2014-11-01
  • 2019-03-02
  • 1970-01-01
  • 2020-08-14
相关资源
最近更新 更多