GO中的优先队列

时间:2019-02-21 14:56:23

标签: algorithm go priority-queue

任何人都可以向我解释一下这件事: 我想在GO中实现优先级队列(接口实现来自link,但价格最低)

我的代码:

pq := make(PriorityQueue, 0)

pq.Push(&Item{value: 0, priority: 0})

heap.Init(&pq)

fmt.Println(heap.Pop(&pq).(*Item))

item := &Item{value: 1, priority: 10}
pq.Push(item)
item = &Item{value: 2, priority: 20}
pq.Push(item)
item = &Item{value: 3, priority: 5}
pq.Push(item)

fmt.Println(heap.Pop(&pq).(*Item))
fmt.Println(heap.Pop(&pq).(*Item))
fmt.Println(heap.Pop(&pq).(*Item))

// Output:
&{0 0 -1}
&{1 10 -1}
&{3 5 -1}
&{2 20 -1}

为什么不输出:

&{0 0 -1}
&{3 5 -1} 
...

3 个答案:

答案 0 :(得分:1)

TLDR 使用heap.Push(...)heap.Pop(...)在队列中添加和删除并保留订单。

问题出在您的设置中。您不应该直接从队列中推送或弹出队列并期望将其定购。调用heap.Init(&pq)将对整个堆进行排序,因此您可以装入东西并立即订购所有东西。

对于您的用例,您应该使用堆实用程序进行推送和弹出。添加到队列时,请使用heap.Push(...)而不是pq.Push(...)

pq := make(PriorityQueue, 0)

heap.Push(&pq, &Item{value: "0", priority: 0, index: 0})
item := &Item{value: "1", priority: 10, index: 1}
heap.Push(&pq, item)
item = &Item{value: "2", priority: 20, index: 2}
heap.Push(&pq, item)
item = &Item{value: "3", priority: 5, index: 3}
heap.Push(&pq, item)

fmt.Println(heap.Pop(&pq).(*Item))
fmt.Println(heap.Pop(&pq).(*Item))
fmt.Println(heap.Pop(&pq).(*Item))
fmt.Println(heap.Pop(&pq).(*Item))

随后的推入和弹出总是将以这种方式进行排序。由于每个项目都是在插入时订购的,因此您无需调用heap.Init(&pq)。这更接近于在推送和爆破声散布的生产环境中使用的实现。

答案 1 :(得分:0)

此特定优先级队列的实现方式,如原始示例所示,应在将项目推入队列后调用heap.Init

pq := make(PriorityQueue, 0)

pq.Push(&Item{value: "0", priority: 0, index: 0})
item := &Item{value: "1", priority: 10, index: 1}
pq.Push(item)
item = &Item{value: "2", priority: 20, index: 2}
pq.Push(item)
item = &Item{value: "3", priority: 5, index: 3}
pq.Push(item)

heap.Init(&pq)

fmt.Println(heap.Pop(&pq).(*Item))
fmt.Println(heap.Pop(&pq).(*Item))
fmt.Println(heap.Pop(&pq).(*Item))
fmt.Println(heap.Pop(&pq).(*Item))

将按预期的优先顺序打印项目。

答案 2 :(得分:0)

首先请注意,您说过您希望优先级最低,但是数字最高,优先级最高。所以应该是20、10、5、0。

在文档中:

  

取出物品;它们以递减的优先级顺序到达。

我只是将您的数据放入doc页面(您提供的链接)中的示例中。 签出:play.golang.org/p/7GyYgJ-HAwi

主要区别是heap.Init(&pq)的位置。

编辑:@ Eli Bendersky提供了我输入我的答案。