-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpriority-queue.go
69 lines (51 loc) · 1.27 KB
/
priority-queue.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
package priorityqueue
import "errors"
type PriorityQueue struct {
values []int
}
func (h *PriorityQueue) Size() int {
return len(h.values)
}
func (h *PriorityQueue) Peek() (int, error) {
if h.Size() == 0 {
return -1, errors.New("queue is empty")
}
return h.values[0], nil
}
func (h *PriorityQueue) Pop() int {
val := h.values[0]
h.values[0] = h.values[len(h.values)-1]
h.values = h.values[:len(h.values)-1]
h.heapifyDown()
return val
}
func (h *PriorityQueue) Add(num int) {
h.values = append(h.values, num)
h.heapifyUp()
}
func (h *PriorityQueue) heapifyUp() {
i := len(h.values) - 1
parentIndex := (i - 1) / 2
for h.values[parentIndex] > h.values[i] {
h.values[parentIndex], h.values[i] = h.values[i], h.values[parentIndex]
i = (i - 1) / 2
parentIndex = (i - 1) / 2
}
}
func (h *PriorityQueue) heapifyDown() {
i := 0
l := len(h.values)
for i*2+1 < l {
leftChildIndex := i*2 + 1
rightChildIndex := i*2 + 2
smallerChildIndex := leftChildIndex
if rightChildIndex < l && h.values[rightChildIndex] < h.values[leftChildIndex] {
smallerChildIndex = rightChildIndex
}
if h.values[i] < h.values[smallerChildIndex] {
break
}
h.values[i], h.values[smallerChildIndex] = h.values[smallerChildIndex], h.values[i]
i = smallerChildIndex
}
}