我在Java文档中找到了以下内容: 排序算法是由Vladimir Yaroslavskiy、Jon Bentley和Joshua Bloch提供的双轴快速排序。该算法在许多数据集上提供O(n log(n))的性能,而其他快速排序算法则会退化为二次性能,并且通常比传统的(单轴)快速排序实现更快。 然后我在谷歌搜索结果中找到了以下内容: 快速排序算法的理论: 从数组中选取一个元素作为枢轴。 重新排列数组,使所有小于枢轴的元素都在枢轴之前,而所有大于枢轴的元素都在枢轴之后(相等的值可以在任意一侧)。完成分区后,枢轴元素位于其最终位置。 递归地对较小元素的子数组和较大元素的子数组进行排序。 与此相比,双轴快速排序: 对于小型数组(长度<17),使用插入排序算法。 选择两个枢轴元素P1和P2。例如,我们可以将第一个元素a[left]作为P1,将最后一个元素a[right]作为P2。 P1必须小于P2,否则它们将被交换。因此,有以下几个部分: 从left+1到L-1的索引i表示元素小于P1的部分一; 从L到K-1的索引i表示元素大于等于P1且小于等于P2的部分二; 从G+1到right-1的索引i表示元素大于P2的部分三; 从K到G的索引i表示待检查的其余元素的部分四。 从部分IV中获取下一个元素a[K],并将其与两个枢轴P1和P2进行比较,然后将其放置在相应的部分I、II或III中。 指针 L、K 和 G 分别按相应方向改变。 在 K ≤ G 的情况下重复步骤 4-5。 枢轴元素 P1 与部分 I 的最后一个元素进行交换,枢轴元素 P2 与部分 III 的第一个元素进行交换。 对于每个部分 I、II 和 III,递归地重复步骤 1-7。
我想强调的是,从算法角度来看(即成本仅考虑比较和交换的次数),2个轴点快速排序和3个轴点快速排序并不比经典的快速排序(使用1个轴点)更好,甚至更糟。但是,在实践中它们更快,因为它们利用了现代计算机体系结构的优势,特别是它们的缓存未命中数更少。因此,如果我们删除所有缓存,只剩下CPU和主内存,我认为2/3个轴点快速排序比经典的快速排序更差。参考资料: 3个轴点快速排序: https://epubs.siam.org/doi/pdf/10.1137/1.9781611973198.6 分析其为何优于经典快速排序: https://arxiv.org/pdf/1412.0193v1.pdf 完整而不太详细的参考资料: https://algs4.cs.princeton.edu/lectures/23Quicksort.pdf
如果您感兴趣,可以看一下他们如何在Java中实现这个算法: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/DualPivotQuicksort.java#DualPivotQuicksort.sort%28int%5B%5D%2Cint%2Cint%2Cint%5B%5D%2Cint%2Cint%29 如源代码所述:“如果可能,使用给定的工作区数组片段对数组的指定范围进行排序。该算法在许多数据集上提供O(n log(n))的性能,而导致其他快速排序算法降级为二次性能,并且通常比传统的(单脉冲)快速排序实现更快。”