Passed
Push — master ( c21857...1d23cf )
by Yo
01:45
created

BinaryTreeFactory::fromLevelOrderList()   B

Complexity

Conditions 8
Paths 6

Size

Total Lines 33
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 8

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 18
c 1
b 0
f 0
nc 6
nop 2
dl 0
loc 33
ccs 19
cts 19
cp 1
crap 8
rs 8.4444
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yoanm\CommonDSA\Factory;
6
7
use SplQueue;
8
use Yoanm\CommonDSA\DataStructure\BinaryTree\NodeInterface as Node;
9
10
class BinaryTreeFactory
11
{
12
    /**
13
     * @TODO write example regarding expecting list format !
14
     *
15
     * @template TNode of Node The actual Node class
16
     * @template TValue of mixed The actual Node value type
17
     *
18
     *
19
     * @param mixed[] $list ⚠ Must be a 0 indexed list, 0 to n consecutive indexes
20
     * @phpstan-param  list<TValue|null> $list
21
     * @phpstan-param callable(TValue $v): TNode $nodeCreator
22
     *
23
     * @phpstan-return ?TNode
24
     */
25 5
    public static function fromLevelOrderList(array $list, callable $nodeCreator): ?Node
26
    {
27 5
        $tailIdx = count($list) - 1;
28 5
        if ($tailIdx < 0 || (0 === $tailIdx && null === $list[0])) {
29 2
            return null;
30
        }
31
32
        /** @var SplQueue<Node> $queue */
33 3
        $queue = new SplQueue();
34
35 3
        $root = call_user_func($nodeCreator, $list[0]); // @phpstan-ignore argument.type
36 3
        $queue->enqueue($root);
37
38 3
        $idx = 1; // Root value already managed, hence 1 rather 0 !
39 3
        while ($idx <= $tailIdx) {
40 3
            $parentNode = $queue->dequeue();
41
42
            // 1. Manage left node value
43 3
            if (null !== $list[$idx]) {
44 3
                $parentNode->left = $node = call_user_func($nodeCreator, $list[$idx]);
45 3
                $queue->enqueue($node);
46
            }
47 3
            ++$idx;
48
49
            // 1. Manage right node value (if it exists !)
50 3
            if ($idx <= $tailIdx && null !== $list[$idx]) {
51 3
                $parentNode->right = $node = call_user_func($nodeCreator, $list[$idx]);
52 3
                $queue->enqueue($node);
53
            }
54 3
            ++$idx;
55
        }
56
57 3
        return $root;
58
    }
59
}
60