structure_old/priority_queue/priority_queue.go

128 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}