1. 选取第一个元素为基数,分别从右(high)往左(high--)查找,找到一个比基数小的数,进行位置交换, 直到 low == high,结束一次排序;然后从 左 往右查找,找到一个比基数大的数,进行位置交换,直到 low == high,结束一次排序;最后将基数 放到 low 位置上。
2. 此时的 low 值代表一次排序后 基数所在的数组下标位置。
3. 通过递归进行 左右子数组排序,直到 low == high
代码如下:
$arr = [49,38,65,97,76,13,27,49];
function partition(&$arr, $low, $high)
{
//$low = 0;
//$high = count($arr) - 1;
$base = $arr[$low];
while($high > $low) {
while($low < $high && $arr[$high] >= $base)
{
$high--;
}
$arr[$low] = $arr[$high];
while($low < $high && $arr[$low] <= $base)
{
$low++;
}
$arr[$high] = $arr[$low];
}
$arr[$low] = $base;
return $low;
}
function quickSort(&$arr, $low, $high)
{
if ($high > $low) {
$pt = partition($arr, $low, $high);
quickSort($arr, $low, $pt-1);
quickSort($arr, $pt+1, $high);
}
}
quickSort($arr, 0, count($arr)-1);
print_r($arr);
下面的排序,是使用到了PHP自带的 array_merge() 数组合并函数,并且通过循环遍历,每次都需要申请内存。
function quickSort1($arr)
{
$len = count($arr);
if ($len <= 1) {
return $arr;
}
$v = $arr[0];
$low = $up = array();
for ($i = 1; $i < $len; ++$i) {
if ($arr[$i] > $v) {
$up[] = $arr[$i];
} else {
$low[] = $arr[$i];
}
}
$low = quickSort($low);
$up = quickSort($up);
$b = array_merge($low, array($v), $up);
//print_r($b)."\n";
return $b;
}
$a = [6,1,3,2,8,5,9];
var_dump(quickSort($a));
待更。。。。
改变第一种方法里的 quickSort方法:
function quickSortMid(&$arr, $low, $high)
{
$size = count($arr);
$mid = ceil(($size-1) / 2); // 当size为偶数时,向上取整。因为当pt 大于 mid时,中位数一定在左边数组,当等于时,中位数也一定包含在数组中
if ($high > $low) {
$pt = partition($arr, $low, $high);
if ($pt > $mid) {
quickSortMid($arr, $low, $pt-1);
}
if ($pt < $mid) {
quickSortMid($arr, $pt+1, $high);
}
if ($pt == $mid) {
$high = $low;
}
}
// 不需要返回值
// echo $low;
// return $mid;
}
function findMid($arr)
{
$size = count($arr);
$mid = ceil(($size - 1) /2);
quickSortMid($arr, 0, $size - 1);
print_r($arr);
// 当为偶数时
if ($size % 2 == 0) {
return ($arr[$mid] + $arr[$mid -1])/2;
} else {
return $arr[$mid];
}
}
$arr = [1,1,4,3];
var_dump(findMid($arr));