structure_old/priority_queue/priority_queue.go
2019-02-13 18:02:01 +08:00

196 lines
3.4 KiB
Go

package plist
import (
"github.com/davecgh/go-spew/spew"
"github.com/emirpasic/gods/trees/avltree"
"github.com/emirpasic/gods/utils"
)
// PriorityQueue 优先队列 适合数据量不大, 加索引
type PriorityQueue struct {
avlIndex *avltree.Tree
indexlimit int
node *Node
size int
comparator utils.Comparator
}
type Node struct {
value interface{}
// prev *Node
next *Node
}
// NewWithInt compare use int
func NewWithInt() *PriorityQueue {
p := new(PriorityQueue)
p.comparator = func(a, b interface{}) int {
if a.(int) > b.(int) {
return 1
}
return -1
}
p.indexlimit = 10
p.avlIndex = avltree.NewWith(p.comparator)
return p
}
func (pq *PriorityQueue) String() string {
content := ""
for cur := pq.node; cur != nil; cur = cur.next {
content += spew.Sprint(cur.value) + "-"
}
if content != "" {
if content[len(content)-1] == '-' {
content = content[:len(content)-1]
}
}
idxContent := ""
for idx := pq.index; idx != nil; idx = idx.next {
idxContent += spew.Sprint(idx.node.value) + "(" + spew.Sprint(idx.nlen) + ")-"
}
return content + "\n" + idxContent
}
func (pq *PriorityQueue) findIndexStart(v interface{}) *Index {
// find the node of index to start
idx := pq.index
for {
if idx.next == nil {
break
}
if pq.comparator(v, idx.next.node.value) > 0 {
break
}
idx = idx.next
}
return idx
}
func (pq *PriorityQueue) Get(index int) (interface{}, bool) {
if index < 0 || index >= pq.size {
return nil, false
}
idx := pq.index
movesize := index
for {
if movesize-idx.nlen <= 0 {
break
} else {
movesize -= idx.nlen
idx = idx.next
}
}
cur := idx.node
for movesize > 0 {
movesize--
cur = cur.next
}
return cur.value, true
}
func (pq *PriorityQueue) Push(v interface{}) {
node := new(Node)
node.value = v
pq.size++
if pq.node == nil {
//创建索引
index := new(Index)
index.nlen = 1
index.node = node
pq.index = index
pq.node = node
return
}
// find the node of index to start
idx := pq.findIndexStart(v)
cur := idx.node
if pq.comparator(v, pq.node.value) > 0 {
pq.node = node
node.next = cur
pq.index.node = pq.node
pq.index.nlen++
return
}
for i := 0; cur.next != nil; i++ {
// 分裂和整理索引
if i >= pq.indexlimit {
if idx.next != nil && idx.next.nlen < pq.indexlimit {
idx.next.nlen += idx.nlen - pq.indexlimit
idx.nlen = pq.indexlimit
idx.next.node = cur
idx = idx.next
} else {
index := new(Index)
index.node = cur
index.nlen = idx.nlen - pq.indexlimit
index.next = idx.next
idx.next = index
idx.nlen = pq.indexlimit
idx = index
}
i = 0
}
if pq.comparator(v, cur.next.value) > 0 {
temp := cur.next
cur.next = node
node.next = temp
idx.nlen++
return
}
cur = cur.next
}
cur.next = node
idx.nlen++
}
func (pq *PriorityQueue) Top() (interface{}, bool) {
return pq.Get(0)
}
// func (pq *PriorityQueue) Bottom() (interface{}, bool) {
// return pq.Get(pq.right - 1)
// }
// func (pq *PriorityQueue) Get(index int) (interface{}, bool) {
// if index < pq.size {
// return pq.Values()[index], true
// }
// return nil, false
// }
// func (pq *PriorityQueue) Values() []interface{} {
// // values := pq.datas[pq.left:pq.right]
// // if !pq.isSorted {
// // utils.Sort(values, pq.comparator)
// // pq.isSorted = true
// // }
// return pq.datas[pq.left:pq.right]
// }