heap中定义了一个最小堆的接口,只要实现这个接口,借助内部定义的PushPop函数,就可以实现最小堆

因为堆排中需要比较大小、交换元素、计算堆大小等操作,所以这个接口巧妙组合了sort.Interface接口,再增加了两个PushPop方法。

下面代码是我尝试实现的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)
}

SyntaxError
199 声望20 粉丝