go语言heap的使用
前言
在写算法的时候,遇到类似前n个最小值,最大值等问题,我们可以很容易想到堆来解。
go语言提供了一个heap的包,而不需要我们自己手动的去实现一个堆。
接下来学习一下它的使用。
container/heap 包的使用
源码分析
- heap里面有一个借口Interface,这个Interface就是我们需要实现的数据集,如下:
可以看到,在数据集里面还定义了一个sort.Interface
点进源码发现这是数据集的排序规则,所以要使用堆操作,我们首先得自定义一个数据集,实现heap接口的五个方法 Len(), Less(), Swap(), Push(), Pop()
例1:实现基于int数据集的二叉堆
模板
// 定义一个基于int数组的堆
type heap []int
// 重写 sort的三个方法
// 长度
func (h heap) Len() int {
return len(h)
}
// 比较规则
func (h heap) Less(i, j int) bool {
// 这里如果是小于,那么实现的是小根堆,如果是大于实现的是大根堆
// 这是Swap的前置交换条件
return h[i] < h[j]
}
// 交换规则
func (h heap) Swap(i, j int) {
h[i], h[j] = h[j], h[i]
}
// 重写heap的push和pop方法
// 看源码知道,push方法只需要在数据集末尾增加值v
func (h *heap) Push(v interface{
}) {
*h = append(*h, v.(int))
}
// 看源码知道,pop方法是将最后一个值删除并返回
// 这个不好理解,按我们的理解,pop应该是取根节点 也就是删除第一个值
// 实际上注意我们使用的是工具包,这个Pop不是真正的Pop
// 工具包的Pop会将根节点和尾节点先进行交换,所以我们此时的Pop只需要删除最后一个值返回就好
func (h *heap) Pop() interface{
} {
last := len(*h)