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

BinaryTreeFactory   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 48
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 19
c 1
b 0
f 0
dl 0
loc 48
ccs 19
cts 19
cp 1
rs 10
wmc 8

1 Method

Rating   Name   Duplication   Size   Complexity  
B fromLevelOrderList() 0 33 8
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