* 目录结构
* 辅助测试的工具类
ArrayUtil.php
<?php
namespace algorithm\sort;
class ArrayUtil {
public static function shuffle(Array &$a) {
$m = count($a);
while ($m) {
$i = rand(0, --$m);
self::swap($a, $i, $m);
}
}
public static function swap(Array &$a, $i, $j) {
if ($i === $j) {
return;
}
$a[$i] = $a[$i] ^ $a[$j];
$a[$j]= $a[$i] ^ $a[$j];
$a[$i] = $a[$i] ^ $a[$j];
}
}
* 基本版归并排序
MergeSort.php
<?php
/**
* Created by PhpStorm.
* User: Mch
* Date: 9/16/18
* Time: 12:10 PM
*/
namespace algorithm\sort;
class MergeSort {
public static function mergesort(Array &$a) {
$length = count($a);
if ($length < 2) {
return;
}
self::_mergesort($a, 0, $length-1);
}
private static function _mergesort(Array &$a, $left, $right) {
if ($left >= $right) {
return;
}
$mid = floor($left + ($right - $left) / 2);
self::_mergesort($a, $left, $mid);
self::_mergesort($a, $mid+1, $right);
self::merge($a, $left, $mid, $right);
}
private static function merge(Array &$a, $left, $mid, $right) {
$result = new \SplFixedArray($right-$left+1);
$i = 0; // index for $result
$il = $left;
$ir = $mid + 1;
while ($il <= $mid && $ir <= $right) {
if ($a[$il] < $a[$ir]) {
$result[$i] = $a[$il++];
} else {
$result[$i] = $a[$ir++];
}
$i++;
}
while ($il <= $mid) {
$result[$i++] = $a[$il++];
}
while ($ir <= $right) {
$result[$i++] = $a[$ir++];
}
// put back
for ($i = $left, $j = 0; $i <= $right; $i++) {
$a[$i] = $result[$j++]; // unshift $result
}
}
public static function main() {
/*
$a = [];
for ($i = 0; $i < 10; $i++) {
array_push($a, $i);
}
require_once 'ArrayUtil.php';
ArrayUtil::shuffle($a);
*/
$a = [8, 2, 9, 0, 7, 3, 6, 5, 4, 1];
self::mergesort($a);
array_walk($a, function($item, $key, $lastIndex) {
printf("%d%s", $item, $key===$lastIndex ? PHP_EOL : ', ');
}, count($a)-1);
}
}
MergeSort::main();
* PHP Comparator 比较大小的类
https://blog.csdn.net/fareast_mzh/article/details/82726436
* merge sort 通用版
MergeSort2.php
<?php
/**
* Created by PhpStorm.
* User: Mch
* Date: 9/16/18
* Time: 12:10 PM
*/
namespace algorithm\sort;
require_once 'Comparator.php';
class MergeSort2 {
protected $comparator;
public function __construct(Comparator $c) {
$this->comparator = $c;
}
public function mergesort(Array &$a) {
$length = count($a);
if ($length < 2) {
return;
}
$this->_mergesort($a, 0, $length-1);
}
private function _mergesort(Array &$a, $left, $right) {
if ($left >= $right) {
return;
}
$mid = floor($left + ($right - $left) / 2);
$this->_mergesort($a, $left, $mid);
$this->_mergesort($a, $mid+1, $right);
$this->merge($a, $left, $mid, $right);
}
private function merge(Array &$a, $left, $mid, $right) {
$result = new \SplFixedArray($right-$left+1);
$i = 0; // index for $result
$il = $left;
$ir = $mid + 1;
while ($il <= $mid && $ir <= $right) {
// if ($a[$il] < $a[$ir]) {
if ($this->comparator->lessThan($a[$il], $a[$ir])) {
$result[$i] = $a[$il++];
} else {
$result[$i] = $a[$ir++];
}
$i++;
}
while ($il <= $mid) {
$result[$i++] = $a[$il++];
}
while ($ir <= $right) {
$result[$i++] = $a[$ir++];
}
// put back
for ($i = $left, $j = 0; $i <= $right; $i++) {
$a[$i] = $result[$j++]; // unshift $result
}
}
}
* test.php
<?php
/**
* Created by PhpStorm.
* User: Mch
* Date: 9/16/18
* Time: 5:40 PM
*/
include './sort/MergeSort2.php';
use algorithm\sort\MergeSort2;
use algorithm\sort\Comparator;
call_user_func(function() {
$ia = [8, 2, 9, 0, 7, 3, 6, 5, 4, 1];
$sa = array_map(function($item) {
return chr( 97 + $item );
}, $ia);
$print_array = function($a) {
array_walk($a, function($item, $key, $lastIndex) {
echo $item, $key===$lastIndex ? PHP_EOL : ', ';
}, count($a)-1);
};
$print_array($sa);
$m = new MergeSort2(new Comparator(function($a, $b) {
return strcmp($a, $b);
}));
$m->mergesort($sa);
$print_array($sa);
});
* run:
$ php test.php
i, c, j, a, h, d, g, f, e, b
a, b, c, d, e, f, g, h, i, j