• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    golang中的container/heap包使用

    发布者: 福建二哥 | 发布时间: 2025-8-14 05:27| 查看数: 38| 评论数: 0|帖子模式

    包 heap 为所有实现了 heap.Interface 的类型提供堆操作。 一个堆即是一棵树, 这棵树的每个节点的值都比它的子节点的值要小, 而整棵树最小的值位于树根(root), 也即是索引 0 的位置上。
    包 heap 采样接口的形式来满足不同的类型的比较。
    1. type Interface interface {
    2.         sort.Interface
    3.         Push(x any) // add x as element Len()
    4.         Pop() any   // remove and return element Len() - 1.
    5. }
    6. // sort.Interface
    7. type Interface interface {
    8.     Len() int
    9.     Less(i, j int) bool
    10.     Swap(i, j int)
    11. }
    复制代码
    因此,你要比较的对象要先实现
    1. heap.Interface
    复制代码

    简单排序
    1. type myHeap []int

    2. func (h *myHeap) Less(i, j int) bool {
    3.         return (*h)[i] < (*h)[j]
    4. }

    5. func (h *myHeap) Swap(i, j int) {
    6.         (*h)[i], (*h)[j] = (*h)[j], (*h)[i]
    7. }

    8. func (h *myHeap) Len() int {
    9.         return len(*h)
    10. }

    11. // 把最后一个弹出,因为最小的值已经被换到了最后
    12. func (h *myHeap) Pop() (v any) {
    13.         *h, v = (*h)[:h.Len()-1], (*h)[h.Len()-1]
    14.         return
    15. }

    16. func (h *myHeap) Push(v any) {
    17.         *h = append(*h, v.(int))
    18. }

    19. // 从小到大排序
    20. func HeapSort(data []int) []int {
    21.         hp := &myHeap{}
    22.         for _, v := range data {
    23.                 heap.Push(hp, v)
    24.         }
    25.         heap.Init(hp)
    26.         res := make([]int, hp.Len())
    27.         for i := 0; hp.Len() > 0; i++ {
    28.                 res[i] = heap.Pop(hp).(int)
    29.         }

    30.         return res
    31. }

    32. // data = 6, 0, 1, 7, 9, 4, 3, 8, 2, 5
    33. // hp 中存储的是 0, 2, 1, 6, 5, 4, 3, 8, 7, 9
    复制代码
    优先队列

    使用一个 priority 字段来表示优先级大小,使用 index 字段来表示索引。
    1. type Item struct {
    2.         value    string
    3.         priority int
    4.         index    int
    5. }
    6. type PriorityQueue []*Item

    7. func (pq PriorityQueue) Len() int { return len(pq) }

    8. func (pq PriorityQueue) Less(i, j int) bool {
    9.         return pq[i].priority > pq[j].priority
    10. }

    11. func (pq PriorityQueue) Swap(i, j int) {
    12.         pq[i], pq[j] = pq[j], pq[i]
    13.         pq[i].index = i
    14.         pq[j].index = j
    15. }

    16. func (pq *PriorityQueue) Push(x any) {
    17.         n := len(*pq)
    18.         item := x.(*Item)
    19.         item.index = n
    20.         *pq = append(*pq, item)
    21. }

    22. func (pq *PriorityQueue) Pop() any {
    23.         old := *pq
    24.         n := len(old)
    25.         item := old[n-1]
    26.         old[n-1] = nil  // avoid memory leak
    27.         item.index = -1 // for safety
    28.         *pq = old[0 : n-1]
    29.         return item
    30. }

    31. func (pq *PriorityQueue) update(item *Item, value string, priority int) {
    32.         item.value = value
    33.         item.priority = priority
    34.         heap.Fix(pq, item.index)
    35. }

    36. func PriorityQueueTest() {
    37.         items := map[string]int{
    38.                 "banana": 3, "apple": 2, "pear": 4,
    39.         }

    40.         pq := make(PriorityQueue, len(items))
    41.         i := 0
    42.         for value, priority := range items {
    43.                 pq[i] = &Item{
    44.                         value:    value,
    45.                         priority: priority,
    46.                         index:    i,
    47.                 }
    48.                 i++
    49.         }
    50.         heap.Init(&pq)

    51.         item := &Item{
    52.                 value:    "orange",
    53.                 priority: 1,
    54.         }
    55.         heap.Push(&pq, item)
    56.         pq.update(item, item.value, 5)

    57.         for pq.Len() > 0 {
    58.                 item := heap.Pop(&pq).(*Item)
    59.                 fmt.Printf("%.2d:%s ", item.priority, item.value)
    60.         }
    61. }
    复制代码
    按时间排序
    1. type TimeSortedQueueItem struct {
    2.         Time  int64
    3.         Value interface{}
    4. }

    5. type TimeSortedQueue []*TimeSortedQueueItem

    6. func (q TimeSortedQueue) Len() int           { return len(q) }
    7. func (q TimeSortedQueue) Less(i, j int) bool { return q[i].Time < q[j].Time }
    8. func (q TimeSortedQueue) Swap(i, j int)      { q[i], q[j] = q[j], q[i] }

    9. func (q *TimeSortedQueue) Push(v interface{}) {
    10.         *q = append(*q, v.(*TimeSortedQueueItem))
    11. }

    12. func (q *TimeSortedQueue) Pop() interface{} {
    13.         n := len(*q)
    14.         item := (*q)[n-1]
    15.         *q = (*q)[0 : n-1]
    16.         return item
    17. }

    18. func NewTimeSortedQueue(items ...*TimeSortedQueueItem) *TimeSortedQueue {
    19.         q := make(TimeSortedQueue, len(items))
    20.         for i, item := range items {
    21.                 q[i] = item
    22.         }
    23.         heap.Init(&q)
    24.         return &q
    25. }

    26. func (q *TimeSortedQueue) PushItem(time int64, value interface{}) {
    27.         heap.Push(q, &TimeSortedQueueItem{
    28.                 Time:  time,
    29.                 Value: value,
    30.         })
    31. }

    32. func (q *TimeSortedQueue) PopItem() interface{} {
    33.         if q.Len() == 0 {
    34.                 return nil
    35.         }

    36.         return heap.Pop(q).(*TimeSortedQueueItem).Value
    37. }
    复制代码
    到此这篇关于golang中的container/heap包使用的文章就介绍到这了,更多相关golang container/heap包内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    来源:互联网
    免责声明:如果侵犯了您的权益,请联系站长(1277306191@qq.com),我们会及时删除侵权内容,谢谢合作!

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表