Jus*_*Jus 5 algorithm priority-queue go
谁能向我解释一下:我想在 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}
Run Code Online (Sandbox Code Playgroud)
为什么不输出:
&{0 0 -1}
&{3 5 -1}
...
Run Code Online (Sandbox Code Playgroud)
小智 5
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))
Run Code Online (Sandbox Code Playgroud)
后续的推送和弹出将始终以这种方式排序。由于每个项目都是在插入时排序的,因此您不需要调用heap.Init(&pq). 这更接近于在推送和弹出散布的生产环境中使用的实现。
这个特定优先级队列的实现方式,您应该在将项目推入队列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))
Run Code Online (Sandbox Code Playgroud)
将按优先顺序打印项目,如预期的那样。