InPlaceSort::heapSort()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 10
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php namespace Mbh\Collection\Traits\Functional;
2
3
/**
4
 * MBHFramework
5
 *
6
 * @link      https://github.com/MBHFramework/mbh-framework
7
 * @copyright Copyright (c) 2017 Ulises Jeremias Cornejo Fandos
8
 * @license   https://github.com/MBHFramework/mbh-framework/blob/master/LICENSE (MIT License)
9
 */
10
11
use Mbh\Collection\Interfaces\Collection as CollectionInterface;
12
use Mbh\Collection\FixedArray;
13
use Mbh\Collection\CallbackHeap;
14
use Traversable;
15
use SplFixedArray;
16
use SplStack;
17
use LimitIterator;
18
19
trait InPlaceSort
20
{
21
    /**
22
     * Fallback behaviour to use the builtin array sort functions
23
     *
24
     * @param callable $callback The callback for comparison
25
     * @return CollectionInterface
26
     */
27
    public function arraySort(callable $callback = null)
28
    {
29
        $array = $this->toArray();
30
31
        if ($callback) {
32
            usort($array, $callback);
33
        } else {
34
            sort($array);
35
        }
36
37
        $this->setValues(SplFixedArray::fromArray($array));
38
39
        return $this;
40
    }
41
42
    /**
43
     * Sort by applying a CallbackHeap and building a new heap
44
     * Can be efficient for sorting large stored objects.
45
     *
46
     * @param callable $callback The comparison callback
47
     * @return CollectionInterface
48
     */
49
    public function heapSort(callable $callback)
50
    {
51
        $h = new CallbackHeap($callback);
52
        foreach ($this as $elem) {
53
            $h->insert($elem);
54
        }
55
56
        $this->setValues(SplFixedArray::fromArray($h->toArray()));
57
58
        return $this;
59
    }
60
61
    /**
62
     * Perform a bottom-up, non-recursive, in-place mergesort.
63
     * Efficient for very-large objects, and written without recursion
64
     * since PHP isn't well optimized for large recursion stacks.
65
     *
66
     * @param callable $callback The callback for comparison
67
     * @return CollectionInterface
68
     */
69
    public function mergeSort(callable $callback)
70
    {
71
        $count = $this->count();
72
        $result = new SplFixedArray($count);
73
74
        for ($k = 1; $k < $count; $k = $k << 1) {
75
            for ($left = 0; ($left + $k) < $count; $left += $k << 1) {
76
                $right = $left + $k;
77
                $rend = min($right + $k, $count);
78
                $m = $left;
79
                $i = $left;
80
                $j = $right;
81
                while ($i < $right && $j < $rend) {
82
                    if ($callback($this[$i], $this[$j]) <= 0) {
83
                        $result[$m] = $this[$i];
84
                        $i++;
85
                    } else {
86
                        $result[$m] = $this[$j];
87
                        $j++;
88
                    }
89
                    $m++;
90
                }
91
                while ($i < $right) {
92
                    $result[$m] = $this[$i];
93
                    $i++;
94
                    $m++;
95
                }
96
                while ($j < $rend) {
97
                    $result[$m] = $this[$j];
98
                    $j++;
99
                    $m++;
100
                }
101
                for ($m = $left; $m < $rend; $m++) {
102
                    $this[$m] = $result[$m];
103
                }
104
            }
105
        }
106
107
        return $this;
108
    }
109
110
    abstract public static function fromItems(Traversable $array);
111
112
    abstract public function copy();
113
114
    abstract public function count(): int;
115
116
    abstract protected function setValues(Traversable $traversable);
117
118
    abstract public function toArray(): array;
119
}
120