package plist import ( "log" "strings" "github.com/davecgh/go-spew/spew" "github.com/emirpasic/gods/trees/avltree" "github.com/emirpasic/gods/utils" ) // PriorityQueue 优先队列 适合数据量不大, 加索引 type PriorityQueue struct { avl *avltree.Tree size int comparator utils.Comparator splitlimit int } func (pq *PriorityQueue) String() string { content := "" iter := pq.avl.Iterator() iter.End() for iter.Prev() { pl := iter.Value().(*PriorityList) cur := pl.head for cur != nil { content += spew.Sprint(cur.value) + "-" cur = cur.next } content = strings.TrimRight(content, "-") content += " ~ " } return content } func NewWithIntComparator() *PriorityQueue { pq := new(PriorityQueue) pq.comparator = func(v1, v2 interface{}) int { if v1.(int) > v2.(int) { return 1 } else if v1.(int) < v2.(int) { return -1 } return 0 } pq.avl = avltree.NewWith(pq.comparator) pq.splitlimit = 8 pq.size = 0 return pq } func (pq *PriorityQueue) Push(value interface{}) { var pl *PriorityList pq.size++ defer func() { if pl.size >= pq.splitlimit { moveIndex := pl.size / 2 cur := pl.head for i := 1; i < moveIndex; i++ { cur = cur.next } log.Println("pq:", pq.String()) temp := cur.next cur.next = nil plsp := &PriorityList{} plsp.head = temp plsp.size = pl.size - moveIndex pl.size = moveIndex pq.avl.Put(plsp.head.value, plsp) log.Println("list:", pl.head.value, pl.String()) log.Println("list:", plsp.head.value, plsp.String()) log.Println("values:", pq.avl.Values()) log.Println("pq:", pq.String(), "\n----------") } }() floor, ok := pq.avl.Floor(value) if ok { pl = floor.Value.(*PriorityList) cur := pl.head pl.size++ if pq.comparator(value, cur.value) > 0 { temp := pl.head pl.head = &Node{value: value} pl.head.next = temp return } for cur.next != nil { if pq.comparator(value, cur.next.value) >= 0 { temp := cur.next cur.next = &Node{value: value} cur.next.next = temp return } cur = cur.next } // next == nil cur.next = &Node{value: value} return } pl = &PriorityList{} pl.head = &Node{value: value} pl.size++ pq.avl.Put(pl.head.value, pl) return }