66 lines
1.2 KiB
Go
66 lines
1.2 KiB
Go
package utils
|
|
|
|
import "errors"
|
|
|
|
var ErrorEmptyHeap = errors.New("attempted to extract from empty heap")
|
|
|
|
// A MinHeap for Uint64
|
|
type Uint32Heap []uint32
|
|
|
|
func (h *Uint32Heap) swap(x, y int) {
|
|
(*h)[x] = (*h)[x] ^ (*h)[y]
|
|
(*h)[y] = (*h)[y] ^ (*h)[x]
|
|
(*h)[x] = (*h)[x] ^ (*h)[y]
|
|
}
|
|
|
|
func (h *Uint32Heap) Insert(new uint32) uint32 {
|
|
*h = append(*h, new)
|
|
|
|
child := len(*h) - 1
|
|
for child != 0 {
|
|
parent := (child - 1) / 2
|
|
if (*h)[parent] > (*h)[child] {
|
|
h.swap(parent, child)
|
|
} else {
|
|
break
|
|
}
|
|
child = parent
|
|
}
|
|
|
|
return (*h)[0]
|
|
}
|
|
|
|
func (h *Uint32Heap) Extract() (uint32, error) {
|
|
if len(*h) == 0 {
|
|
return 0, ErrorEmptyHeap
|
|
}
|
|
min := (*h)[0]
|
|
|
|
(*h)[0] = (*h)[len(*h)-1]
|
|
*h = (*h)[:len(*h)-1]
|
|
|
|
parent := 0
|
|
for {
|
|
left, right := parent*2+1, parent*2+2
|
|
|
|
if (left < len(*h) && (*h)[parent] > (*h)[left]) || (right < len(*h) && (*h)[parent] > (*h)[right]) {
|
|
if right < len(*h) && (*h)[left] > (*h)[right] {
|
|
h.swap(parent, right)
|
|
parent = right
|
|
} else {
|
|
h.swap(parent, left)
|
|
parent = left
|
|
}
|
|
} else {
|
|
return min, nil
|
|
}
|
|
}
|
|
}
|
|
|
|
func (h *Uint32Heap) Peek() (uint32, error) {
|
|
if len(*h) == 0 {
|
|
return 0, ErrorEmptyHeap
|
|
}
|
|
return (*h)[0], nil
|
|
}
|