github.com/searKing/golang/go@v1.2.74/exp/slices/heap.go (about) 1 // Copyright 2023 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package slices 6 7 import ( 8 math_ "github.com/searKing/golang/go/exp/math" 9 "golang.org/x/exp/constraints" 10 ) 11 12 // An MinHeap is a min-heap of slices. 13 type MinHeap[E constraints.Ordered] []E 14 15 func (h MinHeap[E]) Len() int { return len(h) } 16 func (h MinHeap[E]) Less(i, j int) bool { return h[i] < h[j] } 17 func (h MinHeap[E]) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 18 19 func (h *MinHeap[E]) Push(x any) { 20 // Push and Pop use pointer receivers because they modify the slice's length, 21 // not just its contents. 22 *h = append(*h, x.(E)) 23 } 24 25 func (h *MinHeap[E]) Pop() any { 26 old := *h 27 n := len(old) 28 x := old[n-1] 29 *h = old[0 : n-1] 30 return x 31 } 32 33 // An MaxHeap is a max-heap of slices. 34 type MaxHeap[E constraints.Ordered] []E 35 36 func (h MaxHeap[E]) Len() int { return len(h) } 37 func (h MaxHeap[E]) Less(i, j int) bool { return h[i] > h[j] } 38 func (h MaxHeap[E]) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 39 40 func (h *MaxHeap[E]) Push(x any) { 41 // Push and Pop use pointer receivers because they modify the slice's length, 42 // not just its contents. 43 *h = append(*h, x.(E)) 44 } 45 46 func (h *MaxHeap[E]) Pop() any { 47 old := *h 48 n := len(old) 49 x := old[n-1] 50 *h = old[0 : n-1] 51 return x 52 } 53 54 type Heap[S ~[]E, E any] struct { 55 S S 56 57 Size int 58 Comparator func(v1 E, v2 E) int 59 } 60 61 func NewHeap[S ~[]E, E constraints.Ordered](s S) *Heap[S, E] { 62 return &Heap[S, E]{ 63 S: s, 64 Size: 0, 65 Comparator: math_.Compare[E], 66 } 67 } 68 69 func NewHeapFunc[S ~[]E, E any](s S, cmp func(a E, b E) int) *Heap[S, E] { 70 return &Heap[S, E]{ 71 S: s, 72 Size: 0, 73 Comparator: cmp, 74 } 75 } 76 77 func (h Heap[S, E]) Len() int { return h.Size } 78 79 func (h Heap[S, E]) Less(i, j int) bool { 80 if h.Comparator == nil { // nop, don't sort 81 return true 82 } 83 return h.Comparator(h.S[i], h.S[j]) < 0 84 } 85 86 func (h Heap[S, E]) Swap(i, j int) { h.S[i], h.S[j] = h.S[j], h.S[i] } 87 88 func (h *Heap[S, E]) Push(x any) { // add x as element Len() 89 // Push and Pop use pointer receivers because they modify the slice's length, 90 // not just its contents. 91 h.S[h.Size] = x.(E) 92 h.Size++ 93 } 94 95 func (h *Heap[S, E]) Pop() any { // remove and return element Len() - 1. 96 n := h.Size 97 h.Size-- 98 return h.S[n-1] 99 }