堆:数组实现的完全二叉树 leetcode:347
1.堆的接口定义:go默认是小顶堆
type Interface interface {
Len() int //sort.Interface
Less(i, j int) bool
Swap(i, j int)
Push(x interface{})
Pop() interface{}
}
2.使用
1)定义了一个类型,这个类型实现了堆的接口后,此类型就可使用heap包
type IntHeap []int
func (h IntHeap) Len() int { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *IntHeap) Push(x interface{}) {
// Push and Pop use pointer receivers because they modify the slice's length,not just its contents.
*h = append(*h, x.(int))
}
func (h *IntHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
//弹出队尾是因为,heap.pop操作先将堆头尾交换(最小元素到了队尾),再自上而下进行堆化,所以弹出堆最小元素在队尾。
}
2)使用 heap包的push、pop
h := &IntHeap{100,16,4,8,70,2,36,22,5,12}
heap.Init(h) //利用heap包实现 建小顶堆
sort.Sort(h)
heap.Push(h, 3) //插入堆、自下往上堆化
heap.Pop(h) //删除堆顶元素
3.heap源码还有一部分:https://www.cnblogs.com/huxianglin/p/6925119.html
func Push(h Interface, x interface{}) { // heap.Push
h.Push(x) // 此处是自定义的Push接口,将元素放入数组尾部
up(h, h.Len()-1) // 将新放入的元素进行上浮操作,自下往上堆化
}
func Pop(h Interface) interface{} {
n := h.Len() - 1
h.Swap(0, n) // 交换堆头尾元素,交换2、100
down(h, 0, n) // 将100在新堆中进行下沉堆化
return h.Pop() // 此处是自定义pop接口,弹出交换后的尾元素,即弹出2
}
4.总结
heap.Push:入队末尾,自下往上堆化
heap.Pop: 交换队头尾,新头自上往下堆化,新队尾出队