-
Notifications
You must be signed in to change notification settings - Fork 0
/
flatqueue.go
107 lines (82 loc) · 1.6 KB
/
flatqueue.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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package flatqueue
type FlatQueue struct {
ids []int
values []float64
length int
}
func New() *FlatQueue {
return &FlatQueue{}
}
func NewWithCapacity(cap int) *FlatQueue {
return &FlatQueue{
ids: make([]int, 0, cap),
values: make([]float64, 0, cap),
}
}
func (q *FlatQueue) Len() int {
return q.length
}
func (q *FlatQueue) Push(id int, value float64) {
pos := q.length
q.length++
if q.length > len(q.ids) {
q.ids = append(q.ids, id)
q.values = append(q.values, value)
}
for pos > 0 {
parent := (pos - 1) >> 1
parentValue := q.values[parent]
if value > parentValue {
break
}
q.ids[pos] = q.ids[parent]
q.values[pos] = parentValue
pos = parent
}
q.ids[pos] = id
q.values[pos] = value
}
func (q *FlatQueue) Pop() int {
top := q.ids[0]
q.length--
if q.length > 0 {
id := q.ids[q.length]
value := q.values[q.length]
q.ids[0] = id
q.values[0] = value
halfLength := q.length >> 1
pos := 0
for pos < halfLength {
left := (pos << 1) + 1
right := left + 1
bestIndex := q.ids[left]
bestValue := q.values[left]
rightValue := q.values[right]
if right < q.length && rightValue < bestValue {
left = right
bestIndex = q.ids[right]
bestValue = rightValue
}
if bestValue > value {
break
}
q.ids[pos] = bestIndex
q.values[pos] = bestValue
pos = left
}
q.ids[pos] = id
q.values[pos] = value
}
return top
}
func (q *FlatQueue) Peek() int {
return q.ids[0]
}
func (q *FlatQueue) PeekValue() float64 {
return q.values[0]
}
func (q *FlatQueue) Clear() {
q.length = 0
q.ids = q.ids[:0]
q.values = q.values[:0]
}