php shell sort

本文详细介绍了一种改进的Shell排序算法实现,该算法通过引入比较器类来增强排序功能,支持自定义比较逻辑。文章提供了完整的代码示例,包括Shell排序类、比较器类以及数组操作工具类。此外,还展示了如何使用自动加载机制来组织和调用这些类。

* 目录结构

  sort/{ArrayUtil.php,Comparator.php,Shell.php}

  autoload.php

  index.php

* sort/Shell.php

<?php

namespace sort;

class Shell {
    protected $comparator;

    public function __construct(Comparator $c) {
        $this->comparator = $c;
    }

    public function sort(array &$a) {
        $N = count($a);
        $h = 1;
        while ($h < floor($N/3)) {
            $h = 3 * $h + 1;
        }
        while ($h >= 1) {
            for ($i = $h; $i < $N; $i++) {
                for ($j = $i; $j >= $h && $this->comparator->lessThan(
                    $a[$j], $a[$j-$h]); $j -= $h)
                    ArrayUtil::exch($a, $j, $j-$h);
            }
            $h = floor($h/3);
        }
    }
}

* autoload.php

<?php
$prefixList = ['sort', 'dp'];

array_walk($prefixList, function($prefix) {
    spl_autoload_register(function($class) use ($prefix) {
        $base_dir = __DIR__ . DIRECTORY_SEPARATOR. str_replace('\\', '/', $prefix);
        $len = strlen($prefix);
        if (strncmp($prefix, $class, $len) !== 0) {
            return;
        }
        $relative_class = substr($class, $len);
        $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
        if (file_exists($file)) {
            require $file;
        }
    });
}, null);

* sort/Comparator.php

<?php
namespace sort;

class Comparator {
    /** @var callable */
    protected $compare;

    public function __construct(callable $compareFunction = null) {
        if (is_null($compareFunction)) {
            $this->compare = function($a, $b) {
                if ($a === $b) {return 0;}
                return $a > $b ? 1 : -1;
            };
            return;
        }
        $this->compare = $compareFunction;
    }
    /*** @return bool */
    public function equal($a, $b) {
        return call_user_func($this->compare, $a, $b) === 0;
    }

    /*** @return bool */
    public function lessThan($a, $b) {
        return call_user_func($this->compare, $a, $b) < 0;
    }

    /*** @return bool */
    public function greeterThan($a, $b) {
        return call_user_func($this->compare, $a, $b) > 0;
    }

    /*** @return bool */
    public function lessThanOrEqual($a, $b) {
        return $this->lessThan($a, $b) || $this->equal($a, $b);
    }

    /*** @return bool */
    public function greeterThanOrEqual($a, $b) {
        return $this->greeterThan($a, $b) || $this->equal($a, $b);
    }

    public function reverse() {
        $compareOriginal = $this->compare;
        $this->compare = function ($a, $b) use ($compareOriginal) {
            return $compareOriginal($b, $a);
        };
    }
}

* sort/ArrayUtil.php

<?php

namespace sort;

class ArrayUtil {
    public static function shuffle(array &$a) {
        $m = count($a);
        while ($m) {
            $i = rand(0, --$m);
            self::exch($a, $i, $m);
        }
    }

    public static function exch(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];
    }

    public static function some(array $a, callable $c) {
        for ($i = 0, $n = count($a); $i < $n; $i++)
            if ($c( $a[$i] ))
                return true;
        return false;
    }

    public static function isSorted(array $a, callable $cmp) {
        for ($i = 1, $n = count($a); $i < $n; $i++)
            if ($cmp($a[$i], $a[$i-1]) < 0)
                return false;
        return true;
    }
}

* test:

index.php

<?php
include 'autoload.php';

use \sort\ArrayUtil;
use \sort\Comparator;
use \sort\Shell;

$a = [1,2,3,4,5,6];
$numcmp = function($a, $b) {return $a-$b;};
$b = ArrayUtil::isSorted($a, $numcmp);
var_dump($b);   // true
ArrayUtil::exch($a, 0, count($a)-1);
$b = ArrayUtil::isSorted($a, $numcmp);
var_dump($b);   // false

var_dump($b);   // true

$s = ArrayUtil::some($a, function($e) {return $e % 2 === 0;});
var_dump($s); // true
$s = ArrayUtil::some($a, function($e) {return $e > 7;});
var_dump($s); // false
unset($s);
unset($a);

$s = "SHELLSHORTEXAMPLE";
$a = str_split($s);

$shell = new Shell(new Comparator(strcmp));
$shell->sort($a);
echo implode('', $a).PHP_EOL; // AEEEHHLLLMOPRSSTX
var_dump(ArrayUtil::isSorted($a, strcmp)); // bool(true)

$ php index.php

bool(true)

bool(false)

bool(false)

bool(true)

bool(false)

AEEEHHLLLMOPRSSTX

bool(true)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fareast_mzh

打赏个金币

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值