快排及其优化
快排的split实现和partition实现及其优化
快排的思想
快排的核心思想在于数组的划分,,通常我们将数组的第一个元素定义为比较元素,然后将数组中小于比较元素的数放到左边,将大于比较元素的放到右边,
这样我们就将数组拆分成了左右两部分:小于比较元素的数组;大于比较元素的数组。我们再对这两个数组进行同样的拆分,直到拆分到不能再拆分,数组就自然而然地以升序排列了。
split算法
split算法使用一个单向的指针来对数组进行遍历,首先将数组首元素设置为比较元素,然后将第二个开始的元素依次与比较元素比较,如果大于比较元素则跳过,如果小于比较元素,则将其与前面较大的元素进行交换,将数组中所有元素交换完毕后,再将比较元素放到中间位置。简单来说就是让j在前面扫描所有的数,让i记录小于比较元素的值,j扫描到大于比较元素,就往前移动,然后等扫描到小于比较元素的位置就将其交换。
1 | //划分数组 |
partition算法
partition算法使用头尾两个方向相反的指针进行遍历,先将数组第一个元素设置为比较元素,头指针从左至右找到第一个大于比较元素的数,尾指针从右至左找到第一个小于比较元素的数,全部交换完毕后将比较元素放到中间位置。
1 | //划分数组 |
快排优化方法
当元素排列趋近有序或者有大量的相同元素,那么快排会退化成O(n2)的算法,可以从以下几个方面优化:
- 三数取中法(Median-of-Three Partitioning):选择子数组中的三个元素(通常是左端、中间和右端),取它们的中值作为枢纽元素。这样可以减少最坏情况发生的概率,提高排序的效率
- 插入排序优化:在子数组较小(一般小于10个元素)时,采用插入排序而不是继续使用快速排序。插入排序在小数组上的效率较高,可以减少递归的层数,从而提高整体性能
- 随机化:随机选择枢纽元素,以减少最坏情况发生的概率
三点中值法
1 | //三点中值法 |
三值中值和插入排序的实例
1 | import java.util.Arrays; |