快速排序法
如果要做到可以随手写出快速排序算法,那首先你就必须了解快速排序的机制到底是什么样子的。
我们就先从快排的原理入手。
假如我们有一个待排序数组:
$array=array(5,7,4,2,11,10,6);
快排的原理是这个样子的,首先我们清楚快排肯定要用到递归的方法来完成排序,
那么,每一次递归都做了什么工作呢?其实每一次递归的工作非常简单;
1。首先,选出来数组的第一个元素,作为对比值,$array中的就是5
2.然后,从数组第二个值开始,从前往后找到第一个比5大的数字,这是一个for循环,
终止条件就是找到第一个比5大的数字,或者到达数组的末尾。这里我们知道的就是7
3.接下来,再用一个for循环,从后往前找,找到第一个比5小的值,或者到达数组的末尾。这里我们得到了2
这个时候我们对比从前向后找第一次for循环停下来的值对应的键,应该是array[1],也就是i=1;第二次从后向前找的时候,获得的是array[3],也就是j=3;
4.接下里的处理会稍微复杂点,就是,这个时候,我们需要判断,i与j的大小,当i>j的时候,这个时候就等于是完成这两次循环所要做的。但是当i<j的时候,我们需要把i和j对应的值交换,然后继续刚才的两个循环,
直到满足这个循环退出条件并且i>j。
5.如果当两个for循环都找到了符合条件的值,并且i>j的时候,
我们把j对应的值和第一个我们选作对比值的那个值交换,这个时候,我们就完成了递归中一次。
这个时候$array=(4,2,5,7,11,10,6)
6.然后剩下的值分成两个部分,在交换后对比值所在位置前面的,都是比这个对比值小的,他们成为一个数组,
递归下去。在交换后对比值所在位置后面的,分成一个数组,递归下去。
以上就是一次递归所做的东西,我们也叫做快排的一次划分。
数组打印结果为:
如果要做到可以随手写出快速排序算法,那首先你就必须了解快速排序的机制到底是什么样子的。
我们就先从快排的原理入手。
假如我们有一个待排序数组:
$array=array(5,7,4,2,11,10,6);
快排的原理是这个样子的,首先我们清楚快排肯定要用到递归的方法来完成排序,
那么,每一次递归都做了什么工作呢?其实每一次递归的工作非常简单;
1。首先,选出来数组的第一个元素,作为对比值,$array中的就是5
2.然后,从数组第二个值开始,从前往后找到第一个比5大的数字,这是一个for循环,
终止条件就是找到第一个比5大的数字,或者到达数组的末尾。这里我们知道的就是7
3.接下来,再用一个for循环,从后往前找,找到第一个比5小的值,或者到达数组的末尾。这里我们得到了2
这个时候我们对比从前向后找第一次for循环停下来的值对应的键,应该是array[1],也就是i=1;第二次从后向前找的时候,获得的是array[3],也就是j=3;
4.接下里的处理会稍微复杂点,就是,这个时候,我们需要判断,i与j的大小,当i>j的时候,这个时候就等于是完成这两次循环所要做的。但是当i<j的时候,我们需要把i和j对应的值交换,然后继续刚才的两个循环,
直到满足这个循环退出条件并且i>j。
5.如果当两个for循环都找到了符合条件的值,并且i>j的时候,
我们把j对应的值和第一个我们选作对比值的那个值交换,这个时候,我们就完成了递归中一次。
这个时候$array=(4,2,5,7,11,10,6)
6.然后剩下的值分成两个部分,在交换后对比值所在位置前面的,都是比这个对比值小的,他们成为一个数组,
递归下去。在交换后对比值所在位置后面的,分成一个数组,递归下去。
以上就是一次递归所做的东西,我们也叫做快排的一次划分。
其实快速排序之所以称之快速,就是因为,冒泡排序是每次对比只交换相邻的两个值的位置,这样每个值要移动到它最终的排序结果中所对应的位置,可能需要很多次位置的变化。但是快速排序可在一次划分中,就确定你选定的那个对比值在最终排序好的队列中的位置。这就是快排的特点。
思路就是这样,那么代码是怎么实现的呢?如下:
<?php
header('content-type:text/html;charset=utf8 ');
$arr=array(50,2,45,42,6,22,15,11,30,16,13,3);
//调用排序方法
echo "<pre>";
print_r(quick_sort($arr));
快速排序方法及注释
function quick_sort($arr) {
//先判断是否需要继续进行
//初始化两个数组
$left_array = array();//小于标尺的
$right_array = array();//大于标尺的
$length = count($arr);
if($length <= 1) {
return $arr;
}
//如果没有返回,说明数组内的元素个数 多余1个,需要排序
//选择一个标尺
//选择第一个元素
$base_num = $arr[0];
//遍历 除了标尺外的所有元素,按照大小关系放入两个数组内
//注意这里的i一定要等于1,也就是从数组的第二个值开始比较,因为第一个值已经是被选定为对比值了
for($i=1; $i<$length; $i++) {
if($base_num > $arr[$i]) {
//放入左边数组
$left_array[] = $arr[$i];
} else {
//放入右边
$right_array[] = $arr[$i];
}
}
//再分别对 左边 和 右边的数组进行相同的排序处理方式
//递归调用这个函数,并记录结果
$left_array = quick_sort($left_array);
$right_array = quick_sort($right_array);
//合并左边 标尺 右边
return array_merge($left_array, array($base_num), $right_array);
}
数组打印结果为:
Array
(
[0] => 2
[1] => 3
[2] => 6
[3] => 11
[4] => 13
[5] => 15
[6] => 16
[7] => 22
[8] => 30
[9] => 42
[10] => 45
[11] => 50
)