Implementação de fila de prioridade de Golang
package main
import (
"fmt"
"golang.org/x/exp/constraints"
)
type MinHeap[T constraints.Ordered] struct {
Items []T
}
func NewMinHeap[T constraints.Ordered]() *MinHeap[T] {
return &MinHeap[T]{}
}
func getLeftChildIndex(index int) int { return index*2 + 1 }
func getRightChildIndex(index int) int { return index*2 + 2 }
func getParentIndex(index int) int { return (index - 1) / 2 }
func (this *MinHeap[T]) hasLeftChild(index int) bool {
return getLeftChildIndex(index) < len(this.Items)
}
func (this *MinHeap[T]) hasRightChild(index int) bool {
return getRightChildIndex(index) < len(this.Items)
}
func (this *MinHeap[T]) hasParent(index int) bool { return getParentIndex(index) >= 0 }
func (this *MinHeap[T]) leftChild(index int) T { return this.Items[getLeftChildIndex(index)] }
func (this *MinHeap[T]) rightChild(index int) T { return this.Items[getRightChildIndex(index)] }
func (this *MinHeap[T]) parent(index int) T { return this.Items[getParentIndex(index)] }
func (this *MinHeap[T]) swap(indexOne, indexTwo int) {
this.Items[indexOne], this.Items[indexTwo] = this.Items[indexTwo], this.Items[indexOne]
}
func (this *MinHeap[T]) Peek() T {
if len(this.Items) == 0 {
panic("No items to peek")
}
return this.Items[0]
}
func (this *MinHeap[T]) Poll() T {
if len(this.Items) == 0 {
panic("No items to Poll")
}
item := this.Items[0]
this.Items[0] = this.Items[len(this.Items)-1]
this.Items = this.Items[:len(this.Items)-1]
this.HeapifyDown()
return item
}
func (this *MinHeap[T]) Add(item T) {
this.Items = append(this.Items, item)
this.HeapifyUp()
}
func (this *MinHeap[T]) HeapifyUp() {
index := len(this.Items) - 1
for this.hasParent(index) && this.parent(index) > this.Items[index] {
this.swap(getParentIndex(index), index)
index = getParentIndex(index)
}
}
func (this *MinHeap[T]) HeapifyDown() {
index := 0
for this.hasLeftChild(index) {
smallerChildIndex := getLeftChildIndex(index)
if this.hasRightChild(index) && this.rightChild(index) < this.leftChild(index) {
smallerChildIndex = getRightChildIndex(index)
}
if this.Items[index] < this.Items[smallerChildIndex] {
break
} else {
this.swap(index, smallerChildIndex)
index = smallerChildIndex
}
}
}
func main() {
mm := NewMinHeap[int]()
mm.Add(10)
mm.Add(3)
mm.Add(1)
mm.Add(2)
mm.Poll()
fmt.Println(mm.Peek())
}
Ibrahim Albarghouthi