heap中定义了一个最小堆的接口,只要实现这个接口,借助内部定义的Push和Pop函数,就可以实现最小堆
因为堆排中需要比较大小、交换元素、计算堆大小等操作,所以这个接口巧妙组合了sort.Interface接口,再增加了两个Push和Pop方法。
下面代码是我尝试实现的Push和Pop函数
// Heap 最小堆
type Heap interface {
sort.Interface
Push(x any)
Pop() any
}
// Push 压入一个元素,然后向上冒泡
func Push(x int, h Heap) {
h.Push(x)
lastIdx := h.Len() - 1
// 跟父元素对比
for lastIdx > 0 {
parentIdx := (lastIdx - 1) / 2
if !h.Less(lastIdx, parentIdx) {
break
}
h.Swap(lastIdx, parentIdx)
lastIdx = parentIdx
}
}
// Pop 头部元素和底部元素交换,然后返回底部元素,新的头部元素开始向下冒泡
func Pop(h Heap) int {
h.Swap(0, h.Len()-1)
x := h.Pop() // 要返回的
// 然后head节点向下冒泡
headIdx := 0
for {
leftIdx, rightIdx := 2*headIdx+1, 2*headIdx+2
// 此时不存在左右子节点
if leftIdx > h.Len()-1 {
break
}
// 提取左右子节点中最小的,然后再跟父节点比较
minNode := leftIdx
if rightIdx <= h.Len()-1 && h.Less(rightIdx, leftIdx) {
minNode = rightIdx
}
if h.Less(minNode, headIdx) {
h.Swap(minNode, headIdx)
}
headIdx = minNode
}
return x.(int)
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。