PHP快速排序算法

看了C语言版本的快速排序后,我用PHP实现了一遍。

难度在于在一个数组上面进行位置的交换理解

算法

一列很长很长很长的队伍,我要排序,先抽一个队长,然后以队长为准,比队长高的排队长右边,比队长矮的排队长左边。 然后以队长为中界分成两个小分队。 各小分队又抽一个小队长 这个小队长又按照大队长的做法做了一遍……..

此图来源互联网:
这里写图片描述

具体过程

  1. 乱数组中,取第一个数进行参考值。(这个数随你喜欢,在数组中任意一个就可以了。但为了方便,取第一个位置)
  2. 取第一个位置的数值用$key变量临时保存起来。
  3. 分别再用$i ,$j 变量保存起数值的开始和结束位置。($start,$end是固定的位置,下面用到的是变动的位置)
  4. 从右边开始循环寻找,比$key小的数值赋值到$i位置(也就是$key的原本的位置,那个比$key小的位置变成的脏值),如果不符合条件的每找一个位置$j递减。
  5. 从左边开始循环寻找,比$key大的数值或等于$key的赋值到那个比$key小的位置,如果不符合条件的每找一个位置$i递增。(这相当两个参考于$key的大小值,进行了对换,那如果这乱的数组只有3个数值的时候,那不相当于排序?当然现在 那个比$key大的位置也变成的脏值,继续像第四步那样重复做一遍。)
  6. 当循环的位置$i,$j靠近(有些老师说是中间位置,其实是不对的,应该说两位置靠近。)的时候,还剩一个含有脏值的$i位置,就把$\key赋值到\$i位置。为什么要赋值到\$i位置?看列表下面解析。
  7. 大小数值由$key做参考分成了两边,即使是两边,但两边还是乱的,再把这两边的数列递归。(像从第一步开始重做一遍)
  8. 一直递归这样的操作,直到开始位置大于或等于结束位置,数组就排序完了。

问题:两边位置缩小成 左边位置无法大于右边位置时,也就是相邻的两个位置,那为什么$key最终用左边$i的位置?
答案:因为那个位置,从一开始就是$key的让出来的位置,所以最后没人认领的位置应该留给$key,这样数组才不多不少。


代码实现

<?php
$testArray = array();

for ($i=0; $i < 100; $i++) { 
    $testArray[] = rand(1, 100);
}

echo '<pre>';
print_r($testArray);
echo '</pre>';

recursive(0, 99);

echo '<pre>';
print_r($testArray);
echo '</pre>';

function recursive($start, $end) {
    global $testArray;

    if ( $end <= $start ) {
        return;
    }

    $i = $start;
    $j = $end;
    $key = $testArray[$start];

    while( $j > $i ) {
        while( $j > $i && $key < $testArray[$j] ) {
            $j--;
        }
        $testArray[$i] = $testArray[$j];

        while( $j > $i && $key >= $testArray[$i] ) {
            $i++;
        }
        $testArray[$j] = $testArray[$i];
    }

    $testArray[$i] = $key;
    recursive($start, $i-1);
    recursive($i+1, $end);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值