php mergesort 归并排序

* 目录结构

* 辅助测试的工具类

 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

猜你喜欢

转载自blog.csdn.net/fareast_mzh/article/details/82725871