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  }