2010-08-12 4 views
2

Basé sur load balancer demo de Rob Pike, j'ai mis en place ma propre file d'attente prioritaire, mais ma méthode de bruit n'est pas bonne, quelqu'un peut-il me dire ce qui ne va pas?Quel est le problème avec la méthode Pop de ma file d'attente prioritaire?

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) 
    } 
} 

EDIT: en plus de la cthom06 façon a souligné, une autre façon de résoudre ce problème est de créer un tableau de pointeurs comme suit,

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

Répondre

1

EDIT:

Oh, je aurais dû vu cela tout de suite.

heap.Push(&h, &c) 

Vous poussez l'adresse de c, qui est réutilisée à chaque itération de plage. Chaque enregistrement dans le tas est un pointeur vers la même zone en mémoire, qui finit par être Brian. Je ne suis pas sûr si c'est un comportement prévu ou un bogue de compilateur, mais

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

fonctionne autour de lui.

Également: Votre boucle for est incorrecte.

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

devrait le réparer.

+0

C'était tout. Merci. – grokus

+0

J'ai ajouté une autre façon de résoudre ce problème. En utilisant un tableau de pointeurs, je peux éviter de faire des copies de la structure. Merci. – grokus

+0

@grokus encore mieux – cthom06

Questions connexes