github.com/jxskiss/gopkg/v2@v2.14.9-0.20240514120614-899f3e7952b4/collection/heapx/priority_queue.go (about) 1 package heapx 2 3 import "github.com/jxskiss/gopkg/v2/internal/constraints" 4 5 type Ordered interface { 6 constraints.Integer | ~string 7 } 8 9 // PriorityQueue is a heap-based priority queue implementation. 10 // 11 // It can be either min (ascending) or max (descending) oriented/ordered. 12 // The type parameters `P` and `V` specify the type of the underlying 13 // priority and value. 14 // 15 // A PriorityQueue is not safe for concurrent operations. 16 type PriorityQueue[P Ordered, V any] struct { 17 heap Heap[pqItem[P, V]] 18 } 19 20 type pqItem[P Ordered, V any] struct { 21 priority P 22 value V 23 } 24 25 // NewMaxPriorityQueue creates a new maximum oriented PriorityQueue. 26 func NewMaxPriorityQueue[P Ordered, V any]() *PriorityQueue[P, V] { 27 pq := &PriorityQueue[P, V]{} 28 pq.heap.init(func(lhs, rhs pqItem[P, V]) bool { 29 return rhs.priority < lhs.priority 30 }) 31 return pq 32 } 33 34 // NewMinPriorityQueue creates a new minimum oriented PriorityQueue. 35 func NewMinPriorityQueue[P Ordered, V any]() *PriorityQueue[P, V] { 36 pq := &PriorityQueue[P, V]{} 37 pq.heap.init(func(lhs, rhs pqItem[P, V]) bool { 38 return lhs.priority < rhs.priority 39 }) 40 return pq 41 } 42 43 // Len returns the size of the PriorityQueue. 44 func (pq *PriorityQueue[P, V]) Len() int { 45 return pq.heap.Len() 46 } 47 48 // Push adds a value with priority to the PriorityQueue. 49 func (pq *PriorityQueue[P, V]) Push(priority P, value V) { 50 pq.heap.Push(pqItem[P, V]{ 51 priority: priority, 52 value: value, 53 }) 54 } 55 56 // Peek returns the most priority value in the PriorityQueue, 57 // it does not remove the value from the queue. 58 func (pq *PriorityQueue[P, V]) Peek() (priority P, value V, ok bool) { 59 item, ok := pq.heap.Peek() 60 if ok { 61 priority, value = item.priority, item.value 62 } 63 return 64 } 65 66 // Pop removes and returns the most priority value in the PriorityQueue. 67 func (pq *PriorityQueue[P, V]) Pop() (priority P, value V, ok bool) { 68 item, ok := pq.heap.Pop() 69 if ok { 70 priority, value = item.priority, item.value 71 } 72 return 73 }