github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/algorithm/datastructures/minheap/heap_test.go (about) 1 package minheap 2 3 import ( 4 "fmt" 5 "math/rand" 6 "strconv" 7 "testing" 8 "time" 9 ) 10 11 type Task struct { 12 Name string 13 Priority int 14 } 15 16 func taskCompare(v1, v2 interface{}) int { 17 t1, _ := v1.(*Task) 18 t2, _ := v2.(*Task) 19 return t1.Priority - t2.Priority 20 } 21 22 func eqTaskFunc(e, b interface{}) bool { 23 t1, ok1 := e.(*Task) 24 t2, ok2 := b.(*Task) 25 if ok1 && ok2 && t1 == t2 { 26 fmt.Println("删除了 ", t1.Name) 27 return true 28 } 29 return false 30 } 31 32 func generatorTask() []interface{} { 33 rand.Seed(time.Now().Unix()) 34 const size = 10 35 d := make([]interface{}, 0, size) 36 for i := 0; i < size; i++ { 37 p := rand.Intn(300) 38 d = append(d, &Task{ 39 Name: "task-" + strconv.Itoa(i), 40 Priority: p, 41 }) 42 } 43 return d 44 } 45 46 func TestHeap_Remove(t *testing.T) { 47 tasks := generatorTask() 48 for i := 0; i < len(tasks); i++ { 49 fmt.Println(tasks[i]) 50 } 51 fmt.Println("----------------") 52 h := NewHeap(taskCompare) 53 h.Heapify(tasks...) 54 remove := h.Remove(tasks[1], eqTaskFunc) 55 56 fmt.Println("删除 ", remove) 57 for h.Len() != 0 { 58 e := h.Poll() 59 if t, ok := e.(*Task); ok { 60 fmt.Println(t) 61 } 62 } 63 } 64 65 func TestHeap_Add(t *testing.T) { 66 h := NewHeap(taskCompare) 67 h.Heapify(generatorTask()...) 68 cnt := 0 69 for h.Len() != 0 { 70 cnt++ 71 pe := h.Peek().(*Task) 72 pe.Name = pe.Name + "_p" + strconv.Itoa(cnt) 73 e := h.Poll() 74 if t, ok := e.(*Task); ok { 75 fmt.Println(t) 76 } 77 } 78 } 79 80 func Test_topKFrequent(t *testing.T) { 81 ret := topKFrequent([]int{1, 1, 1, 2, 2, 3}, 2) 82 t.Log(ret) 83 } 84 85 // 通过heap 求中位数 , 百分位等问题 86 // 思路: 维护两个堆, 一个最大堆(保存前半部数据),一个最小堆(保存后半部分) 87 // 动态维护: 1 比较插入值的大小,小于大堆top进大堆, 大于小堆top进小堆, 在大堆小堆之间得范围随便插入到哪 88 // 2 维护两堆的数量平衡, 通过堆之间的数据搬迁,使得两个堆的size比例满足中位数 或 百分位的比例 89 90 // 347. Top K Frequent Elements 91 // https://leetcode.com/problems/top-k-frequent-elements/description/ 92 func topKFrequent(nums []int, k int) []int { 93 94 // 统计 95 freqMap := make(map[int]int) 96 for _, v := range nums { 97 if _, ok := freqMap[v]; ok { 98 freqMap[v]++ 99 } else { 100 freqMap[v] = 1 101 } 102 } 103 var fdd []numFrequent 104 for k, v := range freqMap { 105 fdd = append(fdd, numFrequent{num: k, freq: v}) 106 } 107 108 h := NewHeap(func(v1, v2 interface{}) int { 109 i1 := v1.(numFrequent) 110 i2 := v2.(numFrequent) 111 if i1.freq > i2.freq { 112 return 1 113 } else if i1.freq < i2.freq { 114 return -1 115 } else { 116 return 0 117 } 118 }) 119 for _, v := range fdd { 120 if h.Len() < k { 121 h.Add(v) 122 } else if h.Peek().(numFrequent).freq < v.freq { 123 h.Poll() 124 h.Add(v) 125 } 126 } 127 var ret []int 128 for h.Peek() != nil { 129 ret = append(ret, h.Poll().(numFrequent).num) 130 } 131 return ret 132 } 133 134 type numFrequent struct { 135 num int 136 freq int 137 }