github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/container/heap/example_pq_test.go (about) 1 // Copyright 2012 The Go Authors. 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 // This example demonstrates a priority queue built using the heap interface. 6 // 通过堆接口 实现优先级队列的示例 7 package heap_test 8 9 import ( 10 "container/heap" 11 "fmt" 12 ) 13 14 // An Item is something we manage in a priority queue. 15 // 优先级队列中的数据项Item 16 type Item struct { 17 value string // The value of the item; arbitrary. 18 priority int // The priority of the item in the queue. 19 // The index is needed by update and is maintained by the heap.Interface methods. 20 index int // The index of the item in the heap. // Item 在heap中的索引 21 } 22 23 // A PriorityQueue implements heap.Interface and holds Items. 24 // 优先级队列 25 type PriorityQueue []*Item 26 27 func (pq PriorityQueue) Len() int { return len(pq) } 28 29 func (pq PriorityQueue) Less(i, j int) bool { 30 // We want Pop to give us the highest, not lowest, priority so we use greater than here. 31 // 需要返回最大的优先级, 所以这里使用> 32 return pq[i].priority > pq[j].priority 33 } 34 35 func (pq PriorityQueue) Swap(i, j int) { 36 pq[i], pq[j] = pq[j], pq[i] 37 pq[i].index = i // 保存数组索引 38 pq[j].index = j 39 } 40 41 func (pq *PriorityQueue) Push(x interface{}) { 42 n := len(*pq) 43 item := x.(*Item) 44 item.index = n // 保存数组索引 45 *pq = append(*pq, item) 46 } 47 48 func (pq *PriorityQueue) Pop() interface{} { 49 old := *pq 50 n := len(old) 51 item := old[n-1] 52 old[n-1] = nil // avoid memory leak // 手动赋值为Nil, 避免内存泄露 53 item.index = -1 // for safety //设置索引为-1 54 *pq = old[0 : n-1] 55 return item 56 } 57 58 // update modifies the priority and value of an Item in the queue. 59 // 修改优先级队列项的优先级和值,并且调整最小堆(因为返回优先级高的项, 应该算是最大堆) 60 func (pq *PriorityQueue) update(item *Item, value string, priority int) { 61 item.value = value 62 item.priority = priority 63 heap.Fix(pq, item.index) 64 } 65 66 // This example creates a PriorityQueue with some items, adds and manipulates an item, 67 // and then removes the items in priority order. 68 func Example_priorityQueue() { 69 // Some items and their priorities. 70 items := map[string]int{ 71 "banana": 3, "apple": 2, "pear": 4, 72 } 73 74 // Create a priority queue, put the items in it, and 75 // establish the priority queue (heap) invariants. 76 pq := make(PriorityQueue, len(items)) 77 i := 0 78 for value, priority := range items { 79 pq[i] = &Item{ 80 value: value, 81 priority: priority, 82 index: i, 83 } 84 i++ 85 } 86 heap.Init(&pq) // 队列构建堆化 87 88 // Insert a new item and then modify its priority. 89 item := &Item{ 90 value: "orange", 91 priority: 1, 92 } 93 heap.Push(&pq, item) // 插入一个新的堆 94 pq.update(item, item.value, 5) // 修改这个item的优先级为5 95 96 // Take the items out; they arrive in decreasing priority order. 97 // 降序的优先级次序 98 for pq.Len() > 0 { 99 item := heap.Pop(&pq).(*Item) 100 fmt.Printf("%.2d:%s ", item.priority, item.value) 101 } 102 // Output: 103 // 05:orange 04:pear 03:banana 02:apple 104 }