github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/container/heap/example_intheap_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 an integer heap built using the heap interface. 6 package heap_test 7 8 import ( 9 "container/heap" 10 "fmt" 11 ) 12 13 // An IntHeap is a min-heap of ints. 14 // 初始化一个最小堆 示例, 需要实现 堆接口 Push 和 Pop 15 // 还需要实现继承的sort.Interface的三个接口 Len, Less, Swap 16 type IntHeap []int 17 18 func (h IntHeap) Len() int { return len(h) } // 返回堆长度 19 func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } // 比较i 和j 的值, i < j 返回true 20 func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 21 22 func (h *IntHeap) Push(x interface{}) { 23 // Push and Pop use pointer receivers because they modify the slice's length, 24 // not just its contents. 25 // Push 和Pop 使用指针接收, 因为它们会修改slices的长度,而不仅仅只是修改内容 26 // append 表示从数组后面加入新元素 27 *h = append(*h, x.(int)) 28 } 29 30 func (h *IntHeap) Pop() interface{} { 31 // 先用一个临时变量old 指向数组 *h 32 // 得到数组的长度 n 33 // 得到数组最后一个元素 x 34 // 修改 数组的内容, 将最后一个元素删除 35 // 返回最后一个元素, 其实是堆顶元素, 因为heap.Pop() 在调用当前Pop时 先交换了堆顶和堆尾元素 36 old := *h 37 n := len(old) 38 x := old[n-1] 39 *h = old[0 : n-1] 40 return x 41 } 42 43 // This example inserts several ints into an IntHeap, checks the minimum, 44 // and removes them in order of priority. 45 func Example_intHeap() { 46 h := &IntHeap{2, 1, 5} 47 heap.Init(h) // 堆化, 构建最小堆 48 heap.Push(h, 3) // 插入新值,这里是从尾部插入, 所以需要 up 向上比较父节点调整 49 fmt.Printf("minimum: %d\n", (*h)[0]) // 得到最小值 在堆顶,也就是数组元素0 50 for h.Len() > 0 { 51 fmt.Printf("%d ", heap.Pop(h)) // 弹出堆顶元素 52 } 53 // Output: 54 // minimum: 1 55 // 1 2 3 5 56 }