php算法之快速排序

快速排序法

如果要做到可以随手写出快速排序算法,那首先你就必须了解快速排序的机制到底是什么样子的。
我们就先从快排的原理入手。
假如我们有一个待排序数组:
$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
)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值