structure_old/priority_queue/priority_queue.go
2019-01-31 18:39:17 +08:00

139 lines
2.3 KiB
Go

package plist
import (
"github.com/emirpasic/gods/utils"
)
// PriorityQueue 优先队列 适合数据量不大, 加索引
type PriorityQueue struct {
left, right, mid int
datas []interface{}
size int
comparator utils.Comparator
isLeftSorted bool
isRightSorted bool
}
// NewWithInt compare use int
func NewWithInt() *PriorityQueue {
p := new(PriorityQueue)
p.datas = make([]interface{}, 8)
p.comparator = func(a, b interface{}) int {
if a.(int) > b.(int) {
return 1
}
return -1
}
return p
}
func (pq *PriorityQueue) reArrange() {
}
func (pq *PriorityQueue) reMakeMemory() {
var incSize int
if pq.size >= 1048 {
incSize = pq.size / 2
} else {
incSize = pq.size
}
capacity := pq.size + incSize
temp := make([]interface{}, capacity)
mid := capacity / 2
left := mid - pq.size/2
copy(temp[left:], pq.datas[pq.left:pq.right])
pq.datas = temp
pq.left = left
pq.mid = mid
pq.right = pq.size + pq.left
}
func (pq *PriorityQueue) Push(v interface{}) {
if pq.size == 0 {
pq.mid = len(pq.datas) / 2
pq.left = pq.mid
pq.right = pq.mid + 1
pq.datas[pq.mid] = v
} else {
if pq.comparator(v, pq.datas[pq.mid]) > 0 {
if pq.right >= len(pq.datas) {
// 重建 datas
pq.reMakeMemory()
}
pq.datas[pq.right] = v
pq.right++
if pq.isRightSorted {
pq.isRightSorted = false
}
} else {
if pq.left-1 < 0 {
// 重建 datas
pq.reMakeMemory()
}
pq.left--
pq.datas[pq.left] = v
if pq.isLeftSorted {
pq.isLeftSorted = false
}
}
}
pq.size++
}
func (pq *PriorityQueue) PopTop() (interface{}, bool) {
return v, isok
}
func (pq *PriorityQueue) PopBottom() (interface{}, bool) {
return v, isok
}
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.isLeftSorted {
utils.Sort(values[0:pq.size/2], pq.comparator)
pq.isLeftSorted = true
}
if !pq.isRightSorted {
utils.Sort(values[pq.size/2:], pq.comparator)
pq.isRightSorted = true
}
return values
}