本篇文章讲解了快速排序思想、实现方案、优化方案,面试遇到求第K大元素问题解决思路。文章较长,建议空闲时阅读。
快速排序思想
排序数组(下标从l到r),选择l到r之间任意一个数据作为povit(分区点)。
遍历数组,将小于povit到放左边,大于povit到放右边,将povit放中间。处理后,数组l到r的数据分成了3部分,l到p-1之间到数据都是小于povit的,povit在中间,后面p+1到r的数据都是大于povit的。
用递归排序下标l到p-1之间的数据和p+1到r之间的数据,直到区间缩小为1,这时数组就有序了。
递归公式:
quick_sort(l…r) = quick_sort(l…p-1) + quick_sort(p+1…r)
终止条件:
l>=r
参考代码
PHP版
class QuickSort {
/**
* 对数组进行快速排序
* @param $arr
*/
public function quickSort($arr) {
$this->quickSortInternally($arr, 0, count($arr)-1);
return $arr;
}
private function quickSortInternally(array &$arr, int $l, int $r) {
if ($l < $r) {
//获取分区点
$p = $this->partition($arr, $l, $r);
//对子数组进行排序
$this->quickSortInternally($arr, $l, $p-1);
$this->quickSortInternally($arr, $p+1, $r);
}
}
/** 交换数组元素,使枢轴记录到位,并返回其所在位置 */
/** 此时在枢轴记录前的数据都小于它,在其后的数据都大于它 */
private function partition(array &$arr, int $l, int $r) {
//用第一个记录做枢轴记录
$pivot = $arr[$left];
//从数组的两端向中间扫描
while($left < $right) {
while($left < $right && $pivot <= $arr[$right]){
$right--;
}
//比枢轴记录小的交换到左边
$this->swap($arr, $left, $right);
while($left < $right &&