go的优先队列和c++差不多,都是通过大小根堆实现
我们只需要 import 标准库里的 heap,
import "container/heap"
以及实现 heap需要调用五个 接口
func (pq PriorityQueue) Len() int
func (pq PriorityQueue) Less(i, j int) bool
func (pq PriorityQueue) Swap(i, j int)
func (pq *PriorityQueue) Push(x interface{})
func (pq *PriorityQueue) Pop() interface{}
代码如下
package main
import (
"container/heap"
"fmt"
)
type PriorityQueue []int // 这个也可以是自定义结构体
func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool { //
return pq[i] < pq[j] // 小根堆==顺序排序,如果是自定义结构体,需要指定到某个元素
}
func (pq PriorityQueue) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
}
func (pq *PriorityQueue) Push(x interface{}) {
item := x.(int)
*pq = append(*pq, item)
}
func (pq *PriorityQueue) Pop() interface{} {
old := *pq
n := len(old)
item := old[n-1]
old[n-1] = 0
*pq = old[0 : n-1] // 在调用这个函数前,heap会先把最后一个元素和第一个元素兑换,然后这里删除的其实是第一个元素,调用结束后会重新对一个元素排序。【直接删除第一个元素会移动所有元素,性价比低】
return item
}
func sort2(piles []int) {
pqlen := len(piles)
pq := make(PriorityQueue, pqlen)
for i, v := range piles {
pq[0] = v
heap.Fix(&pq, 0) // 如果一开始就知道pq的长度用fix修正顺序即可。否则直接用 heap.Push
}
for pq.Len() > 0 { // 优先队列的劣势,不遍历很难顺序取走所有元素。【建议直接用 sort 排序切片】
fmt.Printf("Processing %s \n", heap.Pop(&pq).(int))
}
}
func main() {
sort2([]int{2, 4, 5})
}