跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

Golang containerHeap堆操作使用示例

Go语言中container/heap需实现heap.Interface接口,通过定义Len、Less、Swap、Push、Pop方法构建最小堆或优先队列,如IntHeap或TaskHeap,使用heap.Init初始化后可进行堆操作。 在 Go 语言中, container/heap 包提供了对堆数据结构的支持,但并没有直接提供一个开箱即用的“Heap”类型。你需要基于 heap.Interface 接口实现自己的堆类型,通常结合切片(slice)来完成。下面是一个使用 container/heap 构建最小堆的操作示例,适用于整数或自定义结构体。 定义一个最小堆结构体 我们通过定义一个包含 int 切片的类型,并实现 heap.Interface 的五个方法:Len、Less、Swap、Push 和 Pop。
type IntHeap []int // Len, Less, Swap 是 slice 的基本操作 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] } // Push 和 Pop 是 heap 包调用的方法,注意接收者是指针 func (h *IntHeap) Push(x interface{}) { *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.Init 初始化一个切片,然后进行插入、删除等操作。
package main import ( "container/heap" "fmt" ) func main() { // 创建并初始化堆 h := &IntHeap{3, 1, 4, 1, 5} heap.Init(h) // 插入元素 heap.Push(h, 2) heap.Push(h, 6) // 弹出最小元素 for h.Len() > 0 { min := heap.Pop(h).(int) fmt.Print(min, " ") // 输出: 1 1 2 3 4 5 6 } fmt.Println() }
扩展:优先队列(含权重的任务) 实际开发中,堆常用于实现优先队列。以下是一个带优先级的任务示例: go语言参考手册 中文CHM版 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译 下载 立即学习 “ go语言免费学习笔记(深入) ”;
type Task struct { Name string Priority int // 数值越小,优先级越高 } type TaskHeap []Task func (th TaskHeap) Len() int { return len(th) } func (th TaskHeap) Less(i, j int) bool { return th[i].Priority < th[j].Priority } func (th TaskHeap) Swap(i, j int) { th[i], th[j] = th[j], th[i] } func (th *TaskHeap) Push(x interface{}) { *th = append(*th, x.(Task)) } func (th *TaskHeap) Pop() interface{} { old := *th n := len(old) task := old[n-1] *th = old[0 : n-1] return task } // 使用示例 func main() { tasks := &TaskHeap{ {"Send email", 2}, {"Backup data", 1}, {"Clean cache", 3}, } heap.Init(tasks) heap.Push(tasks, Task{"Urgent fix", 0}) for tasks.Len() > 0 { t := heap.Pop(tasks).(Task) fmt.Printf("Execute: %s (Priority: %d)\n", t.Name, t.Priority) } }
基本上就这些。只要实现 heap.Interface 的方法,你就能自由地构建最大堆、最小堆或任意排序规则的优先队列。注意 Push 和 Pop 必须定义在指针类型上,因为它们会修改切片本身。不复杂但容易忽略细节。

相关文章