start impl. sort algorithms

This commit is contained in:
Dennis Eichhorn 2019-08-10 23:21:26 +02:00
parent 2d64308b78
commit 64198f0562
43 changed files with 918 additions and 0 deletions

View File

View File

View File

@ -0,0 +1,49 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Sort;
/**
* Bubblesort class.
*
* @package phpOMS\Algorithm\Sort;
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
class BubbleSort implements SortInterface
{
public static function sort(array $list, int $order = SortOrder::ASC) : array
{
$n = \count($list);
do {
$newN = 0;
for ($i = 1; $i < $n; ++$i) {
if ($list[$i - 1]->compare($list[$i], $order)) {
$old = $list[$i - 1];
$list[$i - 1] = $list[$i];
$list[$i] = $old;
$newN = $i;
}
}
$n = $newN;
} while ($n > 1);
return $list;
}
}

View File

View File

View File

@ -0,0 +1,63 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Sort;
/**
* CocktailShakerSort class.
*
* @package phpOMS\Algorithm\Sort;
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
class CocktailShakerSort implements SortInterface
{
public static function sort(array $list, int $order = SortOrder::ASC) : array
{
$start = 0;
$end = \count($list) - 1;
while ($start <= $end) {
$newStart = $end;
$newEnd = $start;
for ($i = $start; $i < $end; ++$i) {
if ($list[$i]->compare($list[$i + 1], $order)) {
$old = $list[$i];
$list[$i] = $list[$i + 1];
$list[$i + 1] = $old;
$newEnd = $i;
}
}
$end = $newEnd - 1;
for ($i = $end; $i >= $start; --$i) {
if ($list[$i]->compare($list[$i + 1], $order)) {
$old = $list[$i];
$list[$i] = $list[$i + 1];
$list[$i + 1] = $old;
$newStart = $i;
}
}
$start = $newStart + 1;
}
return $list;
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Sort;
/**
* CombSort class.
*
* @package phpOMS\Algorithm\Sort;
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
class CombSort implements SortInterface
{
public static function sort(array $list, int $order = SortOrder::ASC) : array
{
$sorted = false;
$n = \count($list);
$gap = $n;
$shrink = 1.3;
while (!$sorted) {
$gap = (int) \floor($gap / $shrink);
if ($gap < 2) {
$gap = 1;
$sorted = true;
}
$i = 0;
while ($i + $gap < $n) {
if ($list[$i]->compare($list[$i + $gap], $order)) {
$old = $list[$i];
$list[$i] = $list[$i + 1];
$list[$i + 1] = $old;
$sorted = false;
}
++$i;
}
}
return $list;
}
}

View File

View File

View File

View File

@ -0,0 +1,45 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Sort;
/**
* GnomeSort class.
*
* @package phpOMS\Algorithm\Sort;
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
class GnomeSort implements SortInterface
{
public static function sort(array $list, int $order = SortOrder::ASC) : array
{
$n = \count($list);
for ($i = 1; $i < $n; ++$i) {
$j = $i;
while ($j > 0 && $list[$j - 1]->compare($list[$j], $order)) {
$old = $list[$j - 1];
$list[$j - 1] = $list[$j];
$list[$j] = $old;
--$j;
}
}
return $list;
}
}

View File

View File

View File

View File

View File

View File

@ -0,0 +1,58 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Sort;
/**
* OddEvenSort class.
*
* @package phpOMS\Algorithm\Sort;
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
class OddEvenSort implements SortInterface
{
public static function sort(array $list, int $order = SortOrder::ASC) : array
{
$sorted = false;
$n = \count($list);
while (!$sorted) {
$sorted = true;
for ($i = 1; $i < $n - 1; $i += 2) {
if ($list[$i]->compare($list[$i + 1], $order)) {
$old = $list[$i];
$list[$i] = $list[$i + 1];
$list[$i + 1] = $old;
$sorted = false;
}
}
for ($i = 0; $i < $n - 1; $i += 2) {
if ($list[$i]->compare($list[$i + 1], $order)) {
$old = $list[$i];
$list[$i] = $list[$i + 1];
$list[$i + 1] = $old;
$sorted = false;
}
}
}
return $list;
}
}

View File

View File

View File

View File

View File

@ -0,0 +1,68 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Sort;
/**
* QuickSort class.
*
* @package phpOMS\Algorithm\Sort;
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
class QuickSort implements SortInterface
{
public static function sort(array $list, int $order = SortOrder::ASC) : array
{
$copy = $list;
self::qsort($copy, 0, \count($list) - 1, $order);
return $copy;
}
private static function qsort(array &$list, int $lo, int $hi, int $order) : void
{
if ($lo < $hi) {
$i = self::partition($list, $lo, $hi, $order);
self::qsort($list, $lo, $i, $order);
self::qsort($list, $i + 1, $hi, $order);
}
}
private static function partition(array &$list, int $lo, int $hi, int $order) : int
{
$pivot = $list[$lo + ((int) (($hi - $lo) / 2))];
while (true) {
while (!$list[$lo]->compare($pivot, $order)) {
++$lo;
}
while ($list[$hi]->compare($pivot, $order)) {
--$hi;
}
if ($lo >= $hi) {
return $hi;
}
$old = $list[$lo];
$list[$lo] = $list[$hi];
$list[$hi] = $old;
++$lo;
--$hi;
}
}
}

View File

View File

View File

@ -0,0 +1,49 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Sort;
/**
* SelectionSort class.
*
* @package phpOMS\Algorithm\Sort;
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
class SelectionSort implements SortInterface
{
public static function sort(array $list, int $order = SortOrder::ASC) : array
{
$n = \count($list);
for ($i = 0; $i < $n - 1; ++$i) {
$min = $i;
for ($j = $i + 1; $j < $n; ++$j) {
if (!$list[$j]->compare($list[$min], $order)) {
$min = $j;
}
}
if ($min !== $i) {
$old = $list[$i];
$list[$i] = $list[$min];
$list[$min] = $old;
}
}
return $list;
}
}

View File

View File

View File

@ -0,0 +1,28 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Sort;
/**
* SortInterface class.
*
* @package phpOMS\Algorithm\Sort;
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
interface SortInterface
{
public static function sort(array $list, int $order = SortOrder::ASC) : array;
}

View File

@ -0,0 +1,31 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Algorithm\Sort
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Sort;
use phpOMS\Stdlib\Base\Enum;
/**
* SortOrder enum.
*
* @package phpOMS\Algorithm\Sort
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
abstract class SortOrder extends Enum
{
public const ASC = 1;
public const DESC = 2;
}

View File

@ -0,0 +1,28 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Algorithm\Sort;
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Algorithm\Sort;
/**
* SortableInterface class.
*
* @package phpOMS\Algorithm\Sort;
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
interface SortableInterface
{
public function compare(SortableInterface $obj, int $order = SortOrder::ASC) : bool;
}

View File

View File

View File

View File

View File

View File

@ -0,0 +1,58 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Algorithm\Sort;
use phpOMS\Algorithm\Sort\BubbleSort;
use phpOMS\Algorithm\Sort\SortableInterface;
use phpOMS\Algorithm\Sort\SortOrder;
require_once __DIR__ . '/../../Autoloader.php';
/**
* @testdox phpOMS\tests\Algorithm\Sort: Bubble sort test
*
* @internal
*/
class BubbleSortTest extends \PHPUnit\Framework\TestCase
{
protected $list = [];
protected function setUp() : void
{
$this->list = [
new NumericElement(5),
new NumericElement(1),
new NumericElement(4),
new NumericElement(2),
new NumericElement(8),
];
}
public function testSortASC() : void
{
$newList = BubbleSort::sort($this->list);
self::assertEquals(
[1, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
public function testSortDESC() : void
{
$newList = BubbleSort::sort($this->list, SortOrder::DESC);
self::assertEquals(
[8, 5, 4, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Algorithm\Sort;
use phpOMS\Algorithm\Sort\CocktailShakerSort;
use phpOMS\Algorithm\Sort\SortableInterface;
use phpOMS\Algorithm\Sort\SortOrder;
require_once __DIR__ . '/../../Autoloader.php';
/**
* @testdox phpOMS\tests\Algorithm\Sort: CocktailShaker sort test
*
* @internal
*/
class CocktailShakerSortTest extends \PHPUnit\Framework\TestCase
{
protected $list = [];
protected function setUp() : void
{
$this->list = [
new NumericElement(5),
new NumericElement(1),
new NumericElement(4),
new NumericElement(2),
new NumericElement(8),
];
}
public function testSortASC() : void
{
$newList = CocktailShakerSort::sort($this->list);
self::assertEquals(
[1, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
public function testSortDESC() : void
{
$newList = CocktailShakerSort::sort($this->list, SortOrder::DESC);
self::assertEquals(
[8, 5, 4, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Algorithm\Sort;
use phpOMS\Algorithm\Sort\CombSort;
use phpOMS\Algorithm\Sort\SortableInterface;
use phpOMS\Algorithm\Sort\SortOrder;
require_once __DIR__ . '/../../Autoloader.php';
/**
* @testdox phpOMS\tests\Algorithm\Sort: Comb sort test
*
* @internal
*/
class CombSortTest extends \PHPUnit\Framework\TestCase
{
protected $list = [];
protected function setUp() : void
{
$this->list = [
new NumericElement(5),
new NumericElement(1),
new NumericElement(4),
new NumericElement(2),
new NumericElement(8),
];
}
public function testSortASC() : void
{
$newList = CombSort::sort($this->list);
self::assertEquals(
[1, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
public function testSortDESC() : void
{
$newList = CombSort::sort($this->list, SortOrder::DESC);
self::assertEquals(
[8, 5, 4, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Algorithm\Sort;
use phpOMS\Algorithm\Sort\GnomeSort;
use phpOMS\Algorithm\Sort\SortableInterface;
use phpOMS\Algorithm\Sort\SortOrder;
require_once __DIR__ . '/../../Autoloader.php';
/**
* @testdox phpOMS\tests\Algorithm\Sort: Gnome sort test
*
* @internal
*/
class GnomeSortTest extends \PHPUnit\Framework\TestCase
{
protected $list = [];
protected function setUp() : void
{
$this->list = [
new NumericElement(5),
new NumericElement(1),
new NumericElement(4),
new NumericElement(2),
new NumericElement(8),
];
}
public function testSortASC() : void
{
$newList = GnomeSort::sort($this->list);
self::assertEquals(
[1, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
public function testSortDESC() : void
{
$newList = GnomeSort::sort($this->list, SortOrder::DESC);
self::assertEquals(
[8, 5, 4, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
}

View File

@ -0,0 +1,35 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Algorithm\Sort;
use phpOMS\Algorithm\Sort\SortableInterface;
use phpOMS\Algorithm\Sort\SortOrder;
require_once __DIR__ . '/../../Autoloader.php';
class NumericElement implements SortableInterface
{
public $value = 0;
public function __construct($value)
{
$this->value = $value;
}
public function compare(SortableInterface $obj, int $order = SortOrder::ASC) : bool
{
return $order === SortOrder::ASC ? $this->value > $obj->value : $this->value < $obj->value;
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Algorithm\Sort;
use phpOMS\Algorithm\Sort\OddEvenSort;
use phpOMS\Algorithm\Sort\SortableInterface;
use phpOMS\Algorithm\Sort\SortOrder;
require_once __DIR__ . '/../../Autoloader.php';
/**
* @testdox phpOMS\tests\Algorithm\Sort: OddEven sort test
*
* @internal
*/
class OddEvenSortTest extends \PHPUnit\Framework\TestCase
{
protected $list = [];
protected function setUp() : void
{
$this->list = [
new NumericElement(5),
new NumericElement(1),
new NumericElement(4),
new NumericElement(2),
new NumericElement(8),
];
}
public function testSortASC() : void
{
$newList = OddEvenSort::sort($this->list);
self::assertEquals(
[1, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
public function testSortDESC() : void
{
$newList = OddEvenSort::sort($this->list, SortOrder::DESC);
self::assertEquals(
[8, 5, 4, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Algorithm\Sort;
use phpOMS\Algorithm\Sort\QuickSort;
use phpOMS\Algorithm\Sort\SortableInterface;
use phpOMS\Algorithm\Sort\SortOrder;
require_once __DIR__ . '/../../Autoloader.php';
/**
* @testdox phpOMS\tests\Algorithm\Sort: Quick sort test
*
* @internal
*/
class QuickSortTest extends \PHPUnit\Framework\TestCase
{
protected $list = [];
protected function setUp() : void
{
$this->list = [
new NumericElement(5),
new NumericElement(1),
new NumericElement(4),
new NumericElement(2),
new NumericElement(8),
];
}
public function testSortASC() : void
{
$newList = QuickSort::sort($this->list);
self::assertEquals(
[1, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
public function testSortDESC() : void
{
$newList = QuickSort::sort($this->list, SortOrder::DESC);
self::assertEquals(
[8, 5, 4, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Algorithm\Sort;
use phpOMS\Algorithm\Sort\SelectionSort;
use phpOMS\Algorithm\Sort\SortableInterface;
use phpOMS\Algorithm\Sort\SortOrder;
require_once __DIR__ . '/../../Autoloader.php';
/**
* @testdox phpOMS\tests\Algorithm\Sort: Selection sort test
*
* @internal
*/
class SelectionSortTest extends \PHPUnit\Framework\TestCase
{
protected $list = [];
protected function setUp() : void
{
$this->list = [
new NumericElement(5),
new NumericElement(1),
new NumericElement(4),
new NumericElement(2),
new NumericElement(8),
];
}
public function testSortASC() : void
{
$newList = SelectionSort::sort($this->list);
self::assertEquals(
[1, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
public function testSortDESC() : void
{
$newList = SelectionSort::sort($this->list, SortOrder::DESC);
self::assertEquals(
[8, 5, 4, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
);
}
}