115 lines
2.1 KiB
Go
115 lines
2.1 KiB
Go
package plist
|
|
|
|
import (
|
|
"github.com/davecgh/go-spew/spew"
|
|
"github.com/emirpasic/gods/utils"
|
|
)
|
|
|
|
// PriorityQueue 优先队列 适合数据量不大, 加索引
|
|
type PriorityQueue struct {
|
|
data []interface{}
|
|
left, right, mid int
|
|
cap int
|
|
size int
|
|
isSorted bool
|
|
comparator utils.Comparator
|
|
}
|
|
|
|
// NewWithInt compare use int
|
|
func NewWithInt() *PriorityQueue {
|
|
p := new(PriorityQueue)
|
|
p.cap = 11
|
|
p.mid = 5
|
|
p.data = make([]interface{}, p.cap, p.cap)
|
|
|
|
p.comparator = func(a, b interface{}) int {
|
|
if a.(int) > b.(int) {
|
|
return 1
|
|
}
|
|
return -1
|
|
}
|
|
return p
|
|
}
|
|
|
|
func (pq *PriorityQueue) String() string {
|
|
|
|
return "(" + spew.Sprint(pq.data[pq.mid]) + "," + spew.Sprint(pq.size) + ")" + spew.Sprint(pq.Values())
|
|
}
|
|
|
|
func (pq *PriorityQueue) reMakeData() {
|
|
var temp []interface{}
|
|
|
|
if pq.cap <= 1024 {
|
|
pq.cap = pq.cap*2 + 1
|
|
temp = make([]interface{}, pq.cap, pq.cap)
|
|
} else {
|
|
pq.cap = pq.cap*5/8*2 + 1
|
|
temp = make([]interface{}, pq.cap, pq.cap)
|
|
}
|
|
|
|
pq.mid = (pq.cap - 1) / 2
|
|
left := pq.mid - pq.size/2
|
|
|
|
copy(temp[left:], pq.data[pq.left:pq.right])
|
|
|
|
pq.left = left
|
|
pq.right = pq.left + pq.size
|
|
|
|
pq.data = temp
|
|
}
|
|
func (pq *PriorityQueue) Push(v interface{}) {
|
|
|
|
if pq.size == 0 {
|
|
pq.data[pq.mid] = v
|
|
pq.left = pq.mid
|
|
pq.right = pq.mid + 1
|
|
pq.size = 1
|
|
return
|
|
}
|
|
|
|
midvalue := pq.data[pq.mid]
|
|
if pq.comparator(v, midvalue) > 0 {
|
|
if pq.left == 0 {
|
|
pq.reMakeData()
|
|
}
|
|
|
|
pq.left--
|
|
pq.data[pq.left] = v
|
|
} else {
|
|
|
|
if pq.right == pq.cap {
|
|
pq.reMakeData()
|
|
}
|
|
|
|
pq.data[pq.right] = v
|
|
pq.right++
|
|
}
|
|
|
|
pq.isSorted = false
|
|
pq.size++
|
|
}
|
|
|
|
// 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.data[pq.left:pq.right]
|
|
if !pq.isSorted {
|
|
utils.Sort(values, pq.comparator)
|
|
pq.isSorted = true
|
|
}
|
|
return values
|
|
}
|