-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheap.go
54 lines (49 loc) · 877 Bytes
/
heap.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package aoc2023
type Heap[T any] struct {
s []T
compare func(a, b T) int
}
func NewHeap[T any](compare func(a, b T) int) *Heap[T] {
return &Heap[T]{compare: compare}
}
func (h *Heap[T]) Push(v T) {
i := len(h.s)
h.s = append(h.s, v)
for {
parent := (i - 1) / 2
if parent == i || h.compare(h.s[parent], v) >= 0 {
break
}
h.s[parent], h.s[i] = h.s[i], h.s[parent]
i = parent
}
}
func (h *Heap[T]) Pop() T {
if len(h.s) == 0 {
panic("empty heap")
}
v := h.s[0]
h.s[0] = h.s[len(h.s)-1]
h.s = h.s[:len(h.s)-1]
i := 0
for {
l := i*2 + 1
if l >= len(h.s) {
break
}
r := l + 1
child := l
if r < len(h.s) && h.compare(h.s[r], h.s[l]) > 0 {
child = r
}
if h.compare(h.s[child], h.s[i]) <= 0 {
break
}
h.s[child], h.s[i] = h.s[i], h.s[child]
i = child
}
return v
}
func (h *Heap[T]) Len() int {
return len(h.s)
}