排序算法之归并排序
归并排序是成功应用分治技术的一个完美例子。
分治法的思想是:(1)将问题的实例划分为同一个问题的几个较小的实例,最好拥有同样的规模;(2)对这些较小的实例求解(一般用递归方法,但在问题规模足够小的时候。有时也会利用另一个算法);(3)如果必要的话,合并这些较小问题的解,以得到原始问题的解。
对于一个需要排序的数组$a[0...n-1],归并排序把它一分为二:$a[0..n/2-1]和$a[n/2...n-1],并对每个子数组递归排序,然后把这两个排好序的子数组合并为一个有序数组。
下面的这个图能够很好地解释归并排序的整个流程

递归的将一个数组分成两部分,直到小的足以解决问题就不再递归(一个数,一定是有序的)。然后再将两个有序的数组合并,最后整个数组就是有序的了。
代码实现:
<?php
/**
* 归并排序
* 递归调用mergeSort来对数组$a排序
* @param $a 一个可排序的数组
* @return $a 非降序排列的数组
*/
function mergeSort(&$a) {
$t = count($a);
if ($t <= 1) {
return;
}
$b = array_slice($a, 0, intval($t / 2)); //array_slice() 函数在数组中根据条件取出一段值,并返回 ***如果数组有字符串键,所返回的数组将保留键名
$c = array_slice($a, intval($t / 2));
mergeSort($b);
mergeSort($c);
merge($b, $c, $a);
}
/**
* 将两个有序数组$y, $z合并为一个有序数组$x
* @param $y, $z, $x
* @return $x
*/
function merge(&$y, &$z, &$x) {
$i = $j = $k = 0;
$p = count($y);
$q = count($z);
while ($i < $p && $j < $q) {
if ($y[$i] < $z[$j]) {
$x[$k] = $y[$i];
$i++;
} else {
$x[$k] = $z[$j];
$j++;
}
$k++;
}
if ($i == $p) {
while ($j < $q) {
$x[$k] = $z[$j];
$j++;
$k++;
}
} else {
while ($i < $p) {
$x[$k] = $y[$i];
$i++;
$k++;
}
}
}
$arr = array(8, 3, 2, 9, 7, 1, 5);
mergeSort($arr);
print_r($arr);
?>

浙公网安备 33010602011771号