MinHeap   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 22
eloc 39
c 2
b 0
f 0
dl 0
loc 108
rs 10

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getRoot() 0 3 1
A push() 0 4 1
A siftDown() 0 10 3
A right() 0 3 1
A count() 0 3 1
A setRoot() 0 4 1
A top() 0 3 1
A pop() 0 15 3
A siftUp() 0 9 3
A left() 0 3 1
A parent() 0 3 1
A __construct() 0 3 1
A getSmallestLeaf() 0 10 3
A compare() 0 3 1
1
<?php
2
3
namespace leetcode\util;
4
5
class MinHeap
6
{
7
    private array $heap;
8
9
    public function __construct()
10
    {
11
        $this->heap = [];
12
    }
13
14
    public function push(int $val): void
15
    {
16
        $this->heap[] = $val;
17
        $this->siftUp(count($this->heap) - 1);
18
    }
19
20
    public function pop()
21
    {
22
        if (empty($this->heap)) {
23
            throw new \InvalidArgumentException('Min heap is empty');
24
        }
25
26
        $leaf = array_pop($this->heap);
27
28
        if (empty($this->heap)) {
29
            return $leaf;
30
        }
31
        $value = $this->getRoot();
32
        $this->setRoot($leaf);
33
34
        return $value;
35
    }
36
37
    public function count(): int
38
    {
39
        return count($this->heap);
40
    }
41
42
    public function top()
43
    {
44
        return current($this->heap);
45
    }
46
47
    public function compare(int $a, int $b): int
48
    {
49
        return $a <=> $b;
50
    }
51
52
    public function getRoot(): int
53
    {
54
        return $this->heap[0];
55
    }
56
57
    public function setRoot(int $leaf): void
58
    {
59
        $this->heap[0] = $leaf;
60
        $this->siftDown(0);
61
    }
62
63
    private function siftUp(int $leaf): void
64
    {
65
        while ($leaf > 0) {
66
            $parent = $this->parent($leaf);
67
            if ($this->compare($this->heap[$leaf], $this->heap[$parent]) > 0) {
68
                break;
69
            }
70
            [$this->heap[$leaf], $this->heap[$parent]] = [$this->heap[$parent], $this->heap[$leaf]];
71
            $leaf = $parent;
72
        }
73
    }
74
75
    private function siftDown(int $node): void
76
    {
77
        $last = (int) floor(count($this->heap) / 2);
78
79
        for ($parent = $node; $parent < $last; $parent = $leaf) {
80
            $leaf = $this->getSmallestLeaf($parent);
81
            if ($this->compare($this->heap[$parent], $this->heap[$leaf]) < 0) {
82
                break;
83
            }
84
            [$this->heap[$leaf], $this->heap[$parent]] = [$this->heap[$parent], $this->heap[$leaf]];
85
        }
86
    }
87
88
    private function getSmallestLeaf(int $parent): int
89
    {
90
        $left = $this->left($parent);
91
        $right = $this->right($parent);
92
93
        if ($right < count($this->heap) && $this->compare($this->heap[$left], $this->heap[$right]) > 0) {
94
            return $right;
95
        }
96
97
        return $left;
98
    }
99
100
    private function left(int $index): int
101
    {
102
        return ($index * 2) + 1;
103
    }
104
105
    private function right(int $index): int
106
    {
107
        return ($index * 2) + 2;
108
    }
109
110
    private function parent(int $index): int
111
    {
112
        return ($index - 1) / 2;
113
    }
114
}
115