package main
import "log"
type PriorityQueue []int
func (pq *PriorityQueue) Init() {
n := len(*pq)
for i := n/2 - 1; i >= 0; i-- {
pq.downheap(i, n)
}
}
func (pq *PriorityQueue) PopFront() int {
n := len(*pq) - 1
ret := (*pq)[0]
(*pq)[0], (*pq)[n] = (*pq)[n], (*pq)[0]
pq.downheap(0, n)
*pq = (*pq)[:len(*pq)-1]
return ret
}
func (pq *PriorityQueue) PushBack(value int) {
*pq = append(*pq, []int{value}...)
pq.upheap(len(*pq))
}
func (pq *PriorityQueue) Delete(idx int) {
n := len(*pq) - 1
oldValue := (*pq)[idx]
if n != idx {
(*pq)[idx], (*pq)[n] = (*pq)[n], (*pq)[idx]
if (*pq)[idx] < oldValue {
pq.downheap(idx, n)
} else {
pq.upheap(idx)
}
}
}
func (pq *PriorityQueue) Update(value int) {
n := len(*pq) + 1
*pq = append(*pq, []int{value}...)
pq.upheap(n)
}
func (pq *PriorityQueue) downheap(parent, length int) {
for {
children := 2*parent + 1
if children >= length || children < 0 {
break
}
child := children // left child
if rightChild := child + 1; rightChild < length && (*pq)[rightChild] > (*pq)[child] {
child = rightChild
}
if (*pq)[child] < (*pq)[parent] {
break
}
(*pq)[child], (*pq)[parent] = (*pq)[parent], (*pq)[child]
parent = child // down
}
}
func (pq *PriorityQueue) upheap(children int) {
for {
parent := (children-1)/2
if children == parent || (*pq)[children] < (*pq)[parent] {
break
}
(*pq)[children], (*pq)[parent] = (*pq)[parent], (*pq)[children]
children = parent // up
}
}
func main() {
pq := PriorityQueue{6, 7, 1, 0, 5, 9, 4, 8, 2, 3}
pq.Init()
log.Println(pq)
for i := 0; i < 10; i++ {
log.Println(pq.PopFront())
}
}