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  }