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 }