structure_old/priority_queue/priority_queue.go
2019-02-14 18:36:19 +08:00

145 lines
2.3 KiB
Go

package plist
import (
"log"
"github.com/emirpasic/gods/utils"
)
// PriorityQueue 优先队列 适合数据量不大, 加索引
type PriorityQueue struct {
data *Tree
Head *AvlNode
Tail *AvlNode
comparator utils.Comparator
}
// NewWithInt compare use int
func NewWithInt() *PriorityQueue {
p := new(PriorityQueue)
p.comparator = func(a, b interface{}) int {
if a.(int) == b.(int) {
return 0
}
if a.(int) > b.(int) {
return 1
}
return -1
}
p.data = NewWith(p.comparator)
return p
}
func (pq *PriorityQueue) String() string {
return pq.data.String()
}
func (pq *PriorityQueue) Top() (interface{}, bool) {
return pq.Head, pq.Head != nil
}
func (pq *PriorityQueue) Bottom() (interface{}, bool) {
return pq.Tail, pq.Tail != nil
}
func (pq *PriorityQueue) Get(index int) (interface{}, bool) {
var cur *AvlNode
if index >= 0 {
cur = pq.Head
for index > 0 && cur != nil {
index--
cur = cur.Prev()
}
} else {
cur = pq.Tail
for index < -1 && cur != nil {
index++
cur = cur.Next()
}
}
return cur.Value, cur != nil
}
// GetNode unsafe 破坏AvlNode属性会破坏整个数据结构
func (pq *PriorityQueue) GetNode(index int) (*AvlNode, bool) {
var cur *AvlNode
if index >= 0 {
cur = pq.Head
for index > 0 && cur != nil {
index--
cur = cur.Prev()
}
} else {
cur = pq.Tail
for index < -1 && cur != nil {
index++
cur = cur.Next()
}
}
return cur, cur != nil
}
func (pq *PriorityQueue) Push(v interface{}) {
pnode := pq.data.Put(v)
if pq.Head == nil {
pq.Head = pnode
pq.Tail = pnode
return
}
if pq.comparator(v, pq.Head.Value) > 0 {
pq.Head = pnode
return
}
if pq.comparator(v, pq.Tail.Value) < 0 {
pq.Tail = pnode
return
}
}
func (pq *PriorityQueue) RemoveNode(node *AvlNode) {
if node == pq.Head {
pq.Head = node.Prev()
}
if node == pq.Tail {
pq.Tail = node.Next()
}
pq.data.remove(node.Value, &node)
}
func (pq *PriorityQueue) Remove(index int) *AvlNode {
node, ok := pq.GetNode(index)
if ok {
if node == pq.Head {
pq.Head = node.Prev()
}
if node == pq.Tail {
pq.Tail = node.Next()
}
next := node.Prev()
log.Println(next, next.Next())
pq.data.remove(node.Value, &next)
return node
}
return nil
}
func (pq *PriorityQueue) Values() []interface{} {
return pq.data.Values()
}