【问题标题】:What's wrong with my Priority Queue's Pop method?我的 Priority Queue Pop 方法有什么问题?
【发布时间】:2011-03-29 00:35:24
【问题描述】:

基于 Rob Pike 的load balancer demo,我实现了自己的优先级队列,但是我的 Pop 方法不对,谁能告诉我哪里出错了?

package main

import (
    "fmt"
    "container/heap"
)

type ClassRecord struct {
    name  string
    grade int
}

type RecordHeap []*ClassRecord

func (p RecordHeap) Len() int { return len(p) }

func (p RecordHeap) Less(i, j int) bool {
    return p[i].grade < p[j].grade
}

func (p *RecordHeap) Swap(i, j int) {
    a := *p
    a[i], a[j] = a[j], a[i]
}

func (p *RecordHeap) Push(x interface{}) {
    a := *p
    n := len(a)
    a = a[0 : n+1]
    r := x.(*ClassRecord)
    a[n] = r
    *p = a
}

func (p *RecordHeap) Pop() interface{} {
    a := *p
    *p = a[0 : len(a)-1]
    r := a[len(a)-1]
    return r
}

func main() {
    a := make([]ClassRecord, 6)
    a[0] = ClassRecord{"John", 80}
    a[1] = ClassRecord{"Dan", 85}
    a[2] = ClassRecord{"Aron", 90}
    a[3] = ClassRecord{"Mark", 65}
    a[4] = ClassRecord{"Rob", 99}
    a[5] = ClassRecord{"Brian", 78}
    h := make(RecordHeap, 0, 100)
    for _, c := range a {
        fmt.Println(c)
        heap.Push(&h, &c)
        fmt.Println("Push: heap has", h.Len(), "items")
    }
    for i, x := 0, heap.Pop(&h).(*ClassRecord); i < 10 && x != nil; i++ {
        fmt.Println("Pop: heap has", h.Len(), "items")
        fmt.Println(*x)
    }
}

编辑:除了 cthom06 指出的方式,另一种解决方法是创建一个指针数组,如下所示,

a := make([]*ClassRecord, 6)
a[0] = &ClassRecord{"John", 80}
a[1] = &ClassRecord{"Dan", 85}
......

【问题讨论】:

    标签: go priority-queue


    【解决方案1】:

    编辑:

    哦,我应该马上看到的。

    heap.Push(&h, &c)
    

    您推送 c 的地址,该地址在每次迭代范围时都会被重用。堆中的每条记录都是指向内存中同一区域的指针,最终是 Brian。我不确定这是预期行为还是编译器错误,但是

    t := c
    heap.Push(&h, &t)
    

    解决它。

    另外:你的 for 循环是错误的。

    for h.Len() > 0 {
        x := heap.Pop(&h...
    

    应该修复它。

    【讨论】:

    • 我添加了另一种方法来解决这个问题。通过使用指针数组,我可以避免复制结构。谢谢。
    猜你喜欢
    • 2015-09-09
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 2014-01-14
    • 1970-01-01
    相关资源
    最近更新 更多