2019-01-31 10:39:17 +00:00
|
|
|
package plist
|
|
|
|
|
|
|
|
import (
|
2019-02-08 22:32:58 +00:00
|
|
|
"github.com/davecgh/go-spew/spew"
|
2019-02-13 10:02:01 +00:00
|
|
|
"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-13 10:54:03 +00:00
|
|
|
index *avltree.Tree
|
2019-02-08 22:32:58 +00:00
|
|
|
indexlimit int
|
2019-02-13 08:47:11 +00:00
|
|
|
|
2019-02-08 22:32:58 +00:00
|
|
|
node *Node
|
|
|
|
size int
|
|
|
|
comparator utils.Comparator
|
|
|
|
}
|
|
|
|
|
|
|
|
type Node struct {
|
|
|
|
value interface{}
|
2019-02-10 17:27:47 +00:00
|
|
|
// prev *Node
|
2019-02-08 22:32:58 +00:00
|
|
|
next *Node
|
2019-01-31 10:39:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewWithInt compare use int
|
|
|
|
func NewWithInt() *PriorityQueue {
|
|
|
|
p := new(PriorityQueue)
|
2019-02-13 10:02:01 +00:00
|
|
|
|
2019-01-31 10:39:17 +00:00
|
|
|
p.comparator = func(a, b interface{}) int {
|
|
|
|
if a.(int) > b.(int) {
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
return -1
|
|
|
|
}
|
2019-02-13 10:02:01 +00:00
|
|
|
|
|
|
|
p.indexlimit = 10
|
2019-02-13 10:54:03 +00:00
|
|
|
p.index = avltree.NewWith(p.comparator)
|
2019-02-13 10:02:01 +00:00
|
|
|
|
2019-01-31 10:39:17 +00:00
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
2019-02-08 22:32:58 +00:00
|
|
|
func (pq *PriorityQueue) String() string {
|
|
|
|
content := ""
|
|
|
|
for cur := pq.node; cur != nil; cur = cur.next {
|
2019-02-10 17:27:47 +00:00
|
|
|
content += spew.Sprint(cur.value) + "-"
|
|
|
|
}
|
2019-01-31 19:57:40 +00:00
|
|
|
|
2019-02-10 17:27:47 +00:00
|
|
|
if content != "" {
|
|
|
|
if content[len(content)-1] == '-' {
|
|
|
|
content = content[:len(content)-1]
|
|
|
|
}
|
2019-01-31 19:57:40 +00:00
|
|
|
}
|
2019-02-13 10:54:03 +00:00
|
|
|
return content
|
2019-02-13 08:47:11 +00:00
|
|
|
}
|
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// func (pq *PriorityQueue) Get(index int) (interface{}, bool) {
|
|
|
|
// if index < 0 || index >= pq.size {
|
|
|
|
// return nil, false
|
|
|
|
// }
|
2019-02-01 11:18:48 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// idx := pq.index
|
|
|
|
// movesize := index
|
|
|
|
// for {
|
|
|
|
// if movesize-idx.nlen <= 0 {
|
|
|
|
// break
|
|
|
|
// } else {
|
|
|
|
// movesize -= idx.nlen
|
|
|
|
// idx = idx.next
|
|
|
|
// }
|
|
|
|
// }
|
2019-02-01 11:18:48 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// cur := idx.node
|
|
|
|
// for movesize > 0 {
|
|
|
|
// movesize--
|
|
|
|
// cur = cur.next
|
|
|
|
// }
|
2019-01-31 10:39:17 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// return cur.value, true
|
|
|
|
// }
|
2019-02-01 11:18:48 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// func (pq *PriorityQueue) Push(v interface{}) {
|
2019-02-01 11:18:48 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// node := &Node{value: v}
|
|
|
|
// pq.size++
|
2019-02-13 10:02:01 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// if pq.node == nil {
|
|
|
|
// //创建索引
|
|
|
|
// pq.index.Put(node, 1)
|
2019-02-13 02:46:30 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// pq.node = node
|
|
|
|
// return
|
|
|
|
// }
|
|
|
|
// // find the node of index to start
|
|
|
|
// fool, ok := pq.index.Ceiling(v)
|
|
|
|
// cur := idx.node
|
2019-02-10 17:27:47 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// if pq.comparator(v, pq.node.value) > 0 {
|
|
|
|
// pq.node = node
|
|
|
|
// node.next = cur
|
2019-02-13 10:02:01 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// pq.index.node = pq.node
|
|
|
|
// pq.index.nlen++
|
|
|
|
// return
|
|
|
|
// }
|
2019-02-01 11:18:48 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// 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
|
2019-02-10 17:27:47 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// }
|
2019-01-31 19:57:40 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// cur.next = node
|
|
|
|
// idx.nlen++
|
2019-01-31 10:39:17 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// }
|
2019-01-31 10:39:17 +00:00
|
|
|
|
2019-02-13 10:54:03 +00:00
|
|
|
// func (pq *PriorityQueue) Top() (interface{}, bool) {
|
|
|
|
// return pq.Get(0)
|
|
|
|
// }
|
2019-01-31 10:39:17 +00:00
|
|
|
|
2019-02-08 22:32:58 +00:00
|
|
|
// func (pq *PriorityQueue) Bottom() (interface{}, bool) {
|
|
|
|
// return pq.Get(pq.right - 1)
|
2019-01-31 19:57:40 +00:00
|
|
|
// }
|
2019-01-31 10:39:17 +00:00
|
|
|
|
2019-02-08 22:32:58 +00:00
|
|
|
// func (pq *PriorityQueue) Get(index int) (interface{}, bool) {
|
|
|
|
// if index < pq.size {
|
|
|
|
// return pq.Values()[index], true
|
|
|
|
// }
|
|
|
|
// return nil, false
|
|
|
|
// }
|
2019-01-31 10:39:17 +00:00
|
|
|
|
2019-02-08 22:32:58 +00:00
|
|
|
// 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]
|
|
|
|
// }
|