递归与快速排序
Posted 南北技术笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了递归与快速排序相关的知识,希望对你有一定的参考价值。
今天我们要说的是快速排序,快速排序也是使用了分治法的一个典型的算法,通过每次选取一个元素作为中间元素,将比这个元素小的放在元素的一侧,比中间元素大的放在另一侧,一直重复上述操作,直到中间元素的两侧都只有1个元素或者没有元素的时候,中间元素和两侧元素的一个组成就是有序的了。
1.排序原理
选取一个元素作为中间元素(我们默认选取待排序序列的第一个元素),将待排序序列中比中间元素小的放在左侧,比中间序列大的放在右侧。
一直重复第1步操作,将分割出的左右两个序列,继续按照第1步的原则进行分割,直到左侧或者右侧元素个数<=1,结束分割。
合并左侧元素,中间元素,右侧元素为一个新的已排序序列。
一直重复第3步操作,直到数据完全有序。
2.举例
待排序数组:[8,4,5,7,1,3,6,2]
第一次分组,得到middle等于8,得到左子组[4,5,7,1,3,6,2]和右子组[]。
判断左子组元素个数不<=1,继续对左子组进行分组,得到middle=4,得到左子组[1,3,2]和右子组[5,7,6]。
左子组元素个数依然不为1,继续对左子组进行分组,得到middle=1,得到左子组[]和右子组[3,2],此时左子组元素个数<1,不再进行分组,对右子组[3,2]进行分组,得到middle=3,左子组[2]和右子组[]。
对左子组[]、middle中间元素3、右子组[]进行合并得到[2,3]。
对左子组[]、middle中间元素1、右子组[2,3]进行合并得到[1,2,3]。
对右子组[5,7,6]进行分组,得到middle=5,左子组[]和右子组[7,6],左子组元素<1,不再进行分组。
对右子组[7,6]进行分组,得到middle=7,左子组[6]和右子组[],此时左子组和右子组元素个数都<=1,不再进行分组。
合并左子组[6]、middle中间元素7,右子组[]得到[6,7]。
合并左子组[]、middle中间元素[5]、右子组[6,7]得到[5,6,7]。
合并左子组[1,2,3]、middle中间元素4、右子组[5,6,7]得到[1,2,3,4,5,6,7]。
合并左子组[1,2,3,4,5,6,7]、middle中间元素8、右子组[]得到[1,2,3,4,5,6,7,8]。
3.排序实现
function quickSort($arr)
{
//递归结束的条件
if (count($arr) <= 1) {
return $arr;
}
$preset = $arr[0];//设定第一个数组的值为整个数组用来分界的分界值
$left = $right = [];
for ($i = 1; $i < count($arr); $i++) {
if ($arr[$i] < $preset) {
$left[] = $arr[$i];
} else {
$right[] = $arr[$i];
}
}
$left = quickSort($left);
$right = quickSort($right);
return array_merge($left, [$preset], $right);
}
$arr = [8,4,5,7,1,3,6,2];
print_r(quickSort($arr));
4.算法分析
快速排序某种角度上和归并排序是类似的,都是将数组分割成一个个的小的序列,再对小的序列进行排序,不过和归并排序不同的点在于,归并排序是将两个小的序列在进行合并,合并的时候,会再进行排序操作,而对于快速排序来说,因为有个中间元素的设置,当两个小的序列时,归并排序中的合并操作就不需要了,因为这次需要合并完成的大的序列也就是有序的了。
5.时间复杂度分析
最坏情况下时间复杂度为O(n²)。最好时间复杂度为O(nlogn)。平均时间复杂度为O(nlogn)。
快速排序时间复杂度推算比较复杂,数学较差,就不在这件事情上花时间了,有兴趣的可以参考这几篇文章了解下。
https://www.zhihu.com/question/22393997,(深巷明朝卖杏花的回答)
https://www.jianshu.com/p/45efd93fadae
6.快速排序的优缺点
快速排序也是使用了分治思想的排序算法,但是相比归并排序来说,他在合并时不再需要对需要合并的序列进行排序,快速排序的主要操作都在分这个操作上,他在分的时候就做了判断,将小于中间元素的放在一侧,大于中间元素的放在另一侧。同样因为不再需要合并的时候对两个序列左排序操作,它也不需要重新申请额外的内存空间去处理,在空间复杂度上比归并排序要好。
快速排序的缺点在于它是一种不稳定的排序,同时算法的复杂度依赖于分区元素的选择,如果不能很好的选择中间元素,算法的时间复杂度可能会降为O(n²)
点个 在看 你最好看
以上是关于递归与快速排序的主要内容,如果未能解决你的问题,请参考以下文章