与上一篇的自顶向下方法相反,我们直接从最小的问题开始解决,最终大问题迎刃而解
实现如下:
其中只有merge_sort改变了
function less($m, $n) {
return $m < $n;
}
function merge(&$a, $lo, $mid, $hi) {
$i = $lo;
$j = $mid+1;
$tmp = array();
foreach ($a as $v) {
$tmp[] = $v;
}
for($m = $lo; $m <= $hi;$m++) {
if($i > $mid) $a[$m] = $tmp[$j++];
else if($j > $hi) $a[$m] = $tmp[$i++];
else if(less($tmp[$i], $tmp[$j])) $a[$m] = $tmp[$i++];
else $a[$m] = $tmp[$j++];
}
}
function merge_sort(&$a) {
$len = count($a);
for($i = 2; $i < $len*2; $i = $i*2) { //先从2个元素开始排序,即11合并;然后22合并,以此类推
for($j = 0; $i*$j < $len; $j++) {
merge($a, $i*$j, $i*$j+intval(($i-1)/2), min(array($i*$j+$i-1, $len)));
}
}
}
$a = array(7, 2, 5, 3, 8, 4, 9, 1, 6);
echo "7-2-5-3-8-4-9-1-6<br/>";
merge_sort($a, 0, count($a)-1);
print_r($a);
输出结果:
array(1, 2, 3, 4, 5, 6, 7, 8, 9);