代码实现
type hp []int
func (h *hp) Init(arr []int) {
n := len(arr)
*h = make([]int, n)
copy(*h, arr)
for i := n/2 - 1; i >= 0; i-- {
h.down(i, n)
}
}
func (h *hp) Push(num int) {
*h = append(*h, num)
h.up(len(*h) - 1)
}
func (h *hp) Pop() int {
v := (*h)[0]
n := len(*h) - 1
(*h)[0], (*h)[n] = (*h)[n], (*h)[0]
h.down(0, n)
*h = (*h)[:n]
return v
}
func (h *hp) up(i int) {
for {
j := (i - 1) / 2 // 父节点
if i == j || (*h)[j] <= (*h)[i] {
break
}
// 交换两个节点
(*h)[j], (*h)[i] = (*h)[i], (*h)[j]
i = j
}
}
func (h *hp) down(i, n int) {
for {
j1 := i*2 + 1
if j1 >= n || j1 < 0 {
break
}
// 找到比较小的那个节点
j := j1 // 左节点
if j2 := j1 + 1; j2 < n && (*h)[j2] < (*h)[j1] {
j = j2 // 右节点
}
// 如果比最小的节点还小,结束下沉
if (*h)[i] < (*h)[j] {
break
}
// 交换两个节点的值,赋值要下沉节点的新位子
(*h)[i], (*h)[j] = (*h)[j], (*h)[i]
i = j
}
}
func main() {
ax := []int{7, 6, 7, 6, 9}
h1.Init(ax)
h1.Push(0)
h1.Push(54)
h1.Push(4)
for i := 0; i < len(ax)+3; i++ {
fmt.Print(h1.Pop(), " ")
}
return
}
输出结果:0 4 6 6 7 7 9 54