structure_old/priority_queue/priority_queue.go

129 lines
2.2 KiB
Go
Raw Normal View History

2019-01-31 10:39:17 +00:00
package plist
import (
2019-02-14 10:36:19 +00:00
"log"
2019-02-17 19:47:08 +00:00
"strings"
2019-02-14 10:36:19 +00:00
2019-02-17 19:47:08 +00:00
"github.com/davecgh/go-spew/spew"
"github.com/emirpasic/gods/trees/avltree"
2019-01-31 10:39:17 +00:00
"github.com/emirpasic/gods/utils"
)
// PriorityQueue 优先队列 适合数据量不大, 加索引
type PriorityQueue struct {
2019-02-15 10:51:21 +00:00
avl *avltree.Tree
2019-02-08 22:32:58 +00:00
size int
comparator utils.Comparator
2019-02-15 10:51:21 +00:00
splitlimit int
2019-02-08 22:32:58 +00:00
}
2019-02-17 19:47:08 +00:00
func (pq *PriorityQueue) String() string {
2019-02-13 08:47:11 +00:00
2019-02-17 19:47:08 +00:00
content := ""
iter := pq.avl.Iterator()
2019-02-18 17:37:01 +00:00
for !iter.Last() {
iter.Next()
}
2019-02-13 10:02:01 +00:00
2019-02-17 19:47:08 +00:00
for iter.Prev() {
pl := iter.Value().(*PriorityList)
2019-02-14 10:36:19 +00:00
2019-02-17 19:47:08 +00:00
cur := pl.head
for cur != nil {
content += spew.Sprint(cur.value) + "-"
cur = cur.next
2019-02-14 10:36:19 +00:00
}
2019-02-17 19:47:08 +00:00
content = strings.TrimRight(content, "-")
content += " "
}
2019-02-14 10:36:19 +00:00
2019-02-17 19:47:08 +00:00
return content
}
func NewWithIntComparator() *PriorityQueue {
pq := new(PriorityQueue)
pq.comparator = func(v1, v2 interface{}) int {
if v1.(int) > v2.(int) {
2019-01-31 10:39:17 +00:00
return 1
2019-02-15 10:51:21 +00:00
} else if v1.(int) < v2.(int) {
return -1
2019-01-31 10:39:17 +00:00
}
2019-02-15 10:51:21 +00:00
return 0
2019-01-31 10:39:17 +00:00
}
2019-02-15 10:51:21 +00:00
pq.avl = avltree.NewWith(pq.comparator)
2019-02-17 19:47:08 +00:00
pq.splitlimit = 8
2019-02-15 10:51:21 +00:00
pq.size = 0
return pq
2019-01-31 10:39:17 +00:00
}
2019-02-15 10:51:21 +00:00
func (pq *PriorityQueue) Push(value interface{}) {
var pl *PriorityList
pq.size++
2019-02-01 11:18:48 +00:00
2019-02-17 19:47:08 +00:00
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())
2019-02-18 17:37:01 +00:00
log.Println("pq:", pq.avl.Values())
2019-02-17 19:47:08 +00:00
log.Println("pq:", pq.String(), "\n----------")
}
}()
2019-02-15 10:51:21 +00:00
floor, ok := pq.avl.Floor(value)
if ok {
2019-02-10 17:27:47 +00:00
2019-02-15 10:51:21 +00:00
pl = floor.Value.(*PriorityList)
cur := pl.head
pl.size++
2019-01-31 10:39:17 +00:00
2019-02-15 10:51:21 +00:00
if pq.comparator(value, cur.value) > 0 {
2019-01-31 10:39:17 +00:00
2019-02-15 10:51:21 +00:00
temp := pl.head
pl.head = &Node{value: value}
pl.head.next = temp
2019-01-31 10:39:17 +00:00
2019-02-15 10:51:21 +00:00
return
2019-02-08 22:32:58 +00:00
}
2019-01-31 10:39:17 +00:00
2019-02-15 10:51:21 +00:00
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
2019-02-10 17:27:47 +00:00
}
2019-02-15 10:51:21 +00:00
cur = cur.next
2019-01-31 10:39:17 +00:00
}
2019-02-15 10:51:21 +00:00
// next == nil
cur.next = &Node{value: value}
return
2019-02-10 17:27:47 +00:00
2019-01-31 10:39:17 +00:00
}
2019-01-31 19:57:40 +00:00
2019-02-15 10:51:21 +00:00
pl = &PriorityList{}
pl.head = &Node{value: value}
pl.size++
2019-02-08 22:32:58 +00:00
2019-02-15 10:51:21 +00:00
pq.avl.Put(pl.head.value, pl)
2019-01-31 10:39:17 +00:00
2019-02-15 10:51:21 +00:00
return
2019-01-31 10:39:17 +00:00
2019-02-15 10:51:21 +00:00
}