dissertation-2-code/utils/heap.go

66 lines
1.2 KiB
Go
Raw Normal View History

2020-11-25 19:35:31 +00:00
package utils
import "errors"
var ErrorEmptyHeap = errors.New("attempted to extract from empty heap")
// A MinHeap for Uint64
2020-11-26 22:10:37 +00:00
type Uint32Heap []uint32
2020-11-25 19:35:31 +00:00
2020-11-26 18:55:29 +00:00
func (h *Uint32Heap) swap(x, y int) {
2020-11-26 22:10:37 +00:00
(*h)[x] = (*h)[x] ^ (*h)[y]
(*h)[y] = (*h)[y] ^ (*h)[x]
(*h)[x] = (*h)[x] ^ (*h)[y]
2020-11-25 19:35:31 +00:00
}
2020-11-26 18:55:29 +00:00
func (h *Uint32Heap) Insert(new uint32) uint32 {
2020-11-26 22:10:37 +00:00
*h = append(*h, new)
2020-11-25 19:35:31 +00:00
2020-11-26 22:10:37 +00:00
child := len(*h) - 1
2020-11-25 19:35:31 +00:00
for child != 0 {
parent := (child - 1) / 2
2020-11-26 22:10:37 +00:00
if (*h)[parent] > (*h)[child] {
2020-11-25 19:35:31 +00:00
h.swap(parent, child)
} else {
break
}
child = parent
}
2020-11-26 22:10:37 +00:00
return (*h)[0]
2020-11-25 19:35:31 +00:00
}
2020-11-26 18:55:29 +00:00
func (h *Uint32Heap) Extract() (uint32, error) {
2020-11-26 22:10:37 +00:00
if len(*h) == 0 {
2020-11-25 19:35:31 +00:00
return 0, ErrorEmptyHeap
}
2020-11-26 22:10:37 +00:00
min := (*h)[0]
2020-11-25 19:35:31 +00:00
2020-11-26 22:10:37 +00:00
(*h)[0] = (*h)[len(*h)-1]
*h = (*h)[:len(*h)-1]
2020-11-25 19:35:31 +00:00
parent := 0
for {
left, right := parent*2+1, parent*2+2
2020-11-26 22:10:37 +00:00
if (left < len(*h) && (*h)[parent] > (*h)[left]) || (right < len(*h) && (*h)[parent] > (*h)[right]) {
if right < len(*h) && (*h)[left] > (*h)[right] {
2020-11-25 19:35:31 +00:00
h.swap(parent, right)
parent = right
} else {
h.swap(parent, left)
parent = left
}
} else {
return min, nil
}
}
}
2020-11-26 18:55:29 +00:00
func (h *Uint32Heap) Peek() (uint32, error) {
2020-11-26 22:10:37 +00:00
if len(*h) == 0 {
2020-11-26 18:55:29 +00:00
return 0, ErrorEmptyHeap
}
2020-11-26 22:10:37 +00:00
return (*h)[0], nil
2020-11-25 19:35:31 +00:00
}