堆(优先队列go语言)

链接:GO 实现优先队列 - 个人文章 - SegmentFault 思否

GO语言heap剖析及利用heap实现优先级队列 - 随风飘雪012 - 博客园 (cnblogs.com)

此文章用于自己学习做的笔记:

Go中,虽然没有直接提供优先队列的实现,不过通过标准库container/heap可以很方便的实现一个简单的优先队列。简单的说就是要实现5个接口就能使用了

type Interface interface {
	sort.Interface    //其中包含了 Less Swap Len
	Push(x interface{}) // add x as element Len()
	Pop() interface{}   // remove and return element Len() - 1.
}

  实现贴2个别人的代码:

package main

import (
    "container/heap"
    "fmt"
)

type Item struct {
    value    string // The value of the item; arbitrary.
    priority int    // The priority of the item in the queue.
}

type PriorityQueue []*Item

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

// 绑定Less方法,这里用的是小于号,生成的是大根堆
func (pq PriorityQueue) Less(i, j int) bool {
    return pq[i].priority > pq[j].priority
}

func (pq PriorityQueue) Swap(i, j int) {
    pq[i], pq[j] = pq[j], pq[i]
}

func (pq *PriorityQueue) Push(x interface{}) {
    item := x.(*Item)
    *pq = append(*pq, item)
}

func (pq *PriorityQueue) Pop() interface{} {
    old := *pq
    n := len(old)
    item := old[n-1]
    old[n-1] = nil
    *pq = old[0 : n-1]
    return item
}

func main() {
    queue := new(PriorityQueue)
    heap.Init(queue)

    heap.Push(queue, &Item{value: "A", priority: 3})
    heap.Push(queue, &Item{value: "B", priority: 6})
    heap.Push(queue, &Item{value: "C", priority: 1})
    heap.Push(queue, &Item{value: "D", priority: 2})

    len := queue.Len()
    fmt.Println("优先队列长度:", len)

    item := (*queue)[0]
    fmt.Println("top 提取值: ", item.value)
    fmt.Println("top 提取优先级: ", item.priority)

    fmt.Println("遍历")
    for queue.Len() > 0 {
        fmt.Println(heap.Pop(queue).(*Item).value)
    }
}
package main

import (
	"container/heap"
	"fmt"
)

type Item struct {
	value    string // 优先级队列中的数据,可以是任意类型,这里使用string
	priority int    // 优先级队列中节点的优先级
	index    int    // index是该节点在堆中的位置
}

// 优先级队列需要实现heap的interface
type PriorityQueue []*Item

// 绑定Len方法
func (pq PriorityQueue) Len() int {
	return len(pq)
}

// 绑定Less方法,这里用的是小于号,生成的是小根堆
func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].priority < pq[j].priority
}

// 绑定swap方法
func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].index, pq[j].index = i, j
}

// 绑定put方法,将index置为-1是为了标识该数据已经出了优先级队列了
func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	*pq = old[0 : n-1]
	item.index = -1
	return item
}

// 绑定push方法
func (pq *PriorityQueue) Push(x interface{}) {
	n := len(*pq)
	item := x.(*Item)
	item.index = n
	*pq = append(*pq, item)
}

// 更新修改了优先级和值的item在优先级队列中的位置
func (pq *PriorityQueue) update(item *Item, value string, priority int) {
	item.value = value
	item.priority = priority
	heap.Fix(pq, item.index)
}

func main() {
	// 创建节点并设计他们的优先级
	items := map[string]int{"二毛": 5, "张三": 3, "狗蛋": 9}
	i := 0
	pq := make(PriorityQueue, len(items)) // 创建优先级队列,并初始化
	for k, v := range items {             // 将节点放到优先级队列中
		pq[i] = &Item{
			value:    k,
			priority: v,
			index:    i}
		i++
	}
	heap.Init(&pq) // 初始化堆
	item := &Item{ // 创建一个item
		value:    "李四",
		priority: 1,
	}
	heap.Push(&pq, item)           // 入优先级队列
	pq.update(item, item.value, 6) // 更新item的优先级
	for len(pq) > 0 {
		item := heap.Pop(&pq).(*Item)
		fmt.Printf("%.2d:%s index:%.2d\n", item.priority, item.value, item.index)
	}
}

输出结果:
03:张三 index:-01
05:二毛 index:-01
06:李四 index:-01
09:狗蛋 index:-01

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值